Hystrix異常處理及線程池劃分

異常處理

異常傳播

在HystrixCommand實現的run()方法中拋出異常時,除了HystrixBadRequestException以外,其餘異常均會被Hystrix認爲命令執行失敗並觸發服務降級的處理邏輯,因此當須要在命令執行中拋出不觸發服務降級的異常時來選擇它。java

在使用註解配置實現Hystrix命令時,能夠忽略指定的異常類型,只須要經過設置@HystrixCommand註解的ignoreExceptions參數,以下:git

@HystrixCommand(fallbackMethod = "getDefaultUser", ignoreExceptions = NullPointerException.class)
    public User findUserById(Long id) {
        return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);
    }

當上述方法拋出NullPointerException的異常時,不會觸發後續的fallback邏輯。github

異常獲取

在傳統的繼承實現Hystrix命令時,能夠在getFallback()方法中經過getExecutionException()方法來獲取具體的異常,而後經過判斷來進入不一樣的處理邏輯。spring

在註解配置方式中,只須要在fallback實現方法的參數中增長Throwable e對象的定義,這樣在方法內部就能夠獲取觸發服務降級的具體異常內容。函數

命令名稱、分組和線程池劃分

繼承實現自定義命令

public UserCommand(RestTemplate restTemplate, Long id) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GroupName")).andCommandKey(HystrixCommandKey.Factory.asKey("CommandName")));
        this.restTemplate = restTemplate;
        this.id = id;
    }

從上面的代碼中能夠看出,咱們並無直接設置命令名稱,而是先調用了withGroupKey來設置命令組名,而後才經過調用andCommandKey來設置命令名。this

在Setter中只有withGroupKey靜態函數能夠建立Setter的實例,所以GroupKey是每一個Setter必須的參數,而CommandKey則是一個可選參數。線程

經過設置命令組,Hystrix會根據組來組織和統計命令的告警、儀表盤等信息。除了上述能夠統計信息以外,Hystrix命令默認的線程劃分也是根據命令分組來實現的。默認狀況下,Hystrix會讓相同組名的命令使用同一個線程池,因此咱們須要在建立Hystrix命令時爲其指定命令組名來實現默認的線程池劃分。rest

Hystrix還提供HystrixThreadPoolKey來對線程池進行設置,經過它能夠實現更細粒度的線程池劃分。code

public UserCommand(RestTemplate restTemplate, Long id) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GroupName"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("CommandName"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolKey")));
        this.restTemplate = restTemplate;
        this.id = id;
    }

在沒有指定HystrixThreadPoolKey的狀況下,會使用命令組的方式來劃分線程池。一般狀況下,咱們儘可能使用HystrixThreadPoolKey來指定線程池的劃分。由於多個不一樣的命令可能從業務邏輯上來看屬於同一個組,可是每每從實現自己上須要跟其餘命令來進行隔離。對象

@HystrixCommand註解

使用註解時只須要設置註解的commandKey、groupKey以及threadPoolKey屬性便可,他分別表示了命令名稱、分組以及線程池劃分。

@HystrixCommand(fallbackMethod = "getDefaultUser", ignoreExceptions = NullPointerException.class,
            commandKey = "findUserById", groupKey = "UserGroup", threadPoolKey = "findUserByIdThread")
    public User findUserById(Long id) {
        return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);
    }

代碼地址

spring-cloud-example

相關文章
相關標籤/搜索