異常處理
在 HystrixCommand 實現的run方法中拋出異常,除了 HystrixBadRequestException之外,其他異常均會被Hystrix 認為命令執行失敗並觸發服務降級處理邏輯,所以當需要在命令中執行拋出不觸發降級的異常時使用他,在使用注解配置實現 Hystrix 命令時,支持忽略指定異常類型功能,只需要通過設置 @HystrixCommand 注冊的 ignoreException 參數,示例代碼如下:
@HystrixCommand (ignoreExceptions = {IllegalStateException.class})
如果拋出了類型為 IllegalStateException 的異常,Hystrix 會將其包裝為 HystrixBadRequestException 拋出,這樣就不會觸發后續的 fallback 邏輯。
如果需要在降級邏輯中獲取觸發的異常,我們可以通過 getExecutionException 方法來獲取具體的異常,如果使用注解的方式,則需要在fallback實現的方法的參數中增加 Throwable e 對象的定義,這樣就可以在方法內部獲取觸發服務降級的具體異常內容,示例代碼如下:
@HystrixCommand (ignoreExceptions = {IllegalStateException.class},fallbackMethod="helloFallback")
@GET
@Path ("get")
public String get(@QueryParam ("id") int id, @QueryParam ("name") String name) {
throw new RuntimeException("get command failed.");
}
public String helloFallback(int id, String name, Throwable e) {
return "error id=" + id + "\tname=" + name + "\tthrowable=" + e.getMessage();
}
請求緩存
當系統用戶不斷增長時,每個微服務需要承受的並發壓力也越來越大,在分布式環境中,通常壓力來自對依賴服務的調用,因為親戚依賴服務的資源需要通過通信來實現,這樣的依賴方式比起進程內的調用方式會引起一部分的性能損失,在高並發的場景下,Hystrix 提供了請求緩存的功能,我們可以方便的開啟和使用請求緩存來優化系統,達到減輕高並發時的請求線程消耗、降低請求響應時間的效果
開啟請求緩存功能
Spring Cloud Hystrix 請求緩存的使用非常簡單,我們只需要在實現 HystrixCommand 或 HystrixObservableCommand 時,通過重載 getCacheKey()方法來開啟請求緩存。
public class HelloGetCommand extends HystrixCommand<String> {
private RestTemplate restTemplate;
public HelloGetCommand(Setter setter, RestTemplate restTemplate) {
super(setter);
this.restTemplate= restTemplate;
}
@Override
protected String run() throws Exception {
ResponseEntity<String> responseEntity=
restTemplate(getForEntity("http://ORG.DRSOFT.WEBSERVICE.HELLOSERVICE/hello/get", String.class);
return responseEntity.getBody();
}
@Override
protected String getFallback() {
return "error id=" + id + "\tname=" + name;
}
@Override
protected String getCacheKey() {
return"get";
}
}
調用時候還需要在當前線程執行 HystrixRequestContext.initializeContext() 並且在結束時候需要進行釋放,而且在Hystrix中帶緩存的command是必須在request中調用的,示例代碼如下:
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
HystrixCommand<String> hystrixCommand = new HelloGetCommand(setter, restTemplate);
return hystrixCommand.execute();
} finally {
context.shutdown();
}
清理失效緩存
在請求緩存時,如果只是讀操作,那么不需要考慮緩存內容是否正確的問題,但是如果請求命令中還有更新數據的寫操作,那么緩存中的數據就需要我們在進行寫操作時及時處理,以防止讀操作的請求命令獲取到失效的數據,我們可以使用 HystrixRequestCache.clear 方法來進行緩存清理,示例代碼如下:
/**
* 清除緩存
*/
public void flushCache() {
HystrixRequestCache.getInstance(this.getCommandKey()
, HystrixConcurrencyStrategyDefault.getInstance()).clear("get");
}