本文節選自《瘋狂Spring Cloud微服務架構實戰》html
京東購買地址:https://item.jd.com/12256011.htmljava
噹噹網購買地址:http://product.dangdang.com/25201393.htmlgit
Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993github
使用Hystrix時,能夠爲命令設置屬性,如下的代碼片段,爲一個命令設置了執行的超時時間:架構
public MyCommand(boolean isTimeout) { super( Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withExecutionTimeoutInMilliseconds(500)) ); }
以上的配置僅對該命令生效,設置了命令的超時時間爲500毫秒,該配置項的默認值爲1秒,若是想對全局生效,可使用如下的代碼片段:微服務
ConfigurationManager .getConfigInstance() .setProperty( "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", 500);
以上的代碼片段,一樣設置了命令超時時間爲500毫秒,但對全局有效。除了超時的配置外,還須要瞭解一下命令的相關名稱,能夠爲命令設置如下名稱:測試
如下的代碼片段,分別設置以上的3個Key:ui
public RunCommand(String msg) { super( Setter.withGroupKey( HystrixCommandGroupKey.Factory.asKey("group-key")) .andCommandKey(HystrixCommandKey.Factory.asKey("command-key")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("pool-key")) ); }
Hystrix的配置衆多,後面章節的案例會涉及部分的配置,讀者若是想了解更多的配置,可到如下的地址查看:https://github.com/Netflix/Hystrix/wiki/Configurationspa
根據前面章節的流程圖可知,至少會有3種狀況觸發回退(fallback):.net
在命令中,實現父類(HystrixCommand)的getFallback()方法,便可實現回退,當以上的狀況發生時,將會執行回退方法。前面的例子中,已經展現了「執行命令失敗」的回退,下面測試一下斷路器被打開時的回退,詳細請見代碼清單6-7。
代碼清單6-7:
06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\fallback\FallbackTest.java
public class FallbackTest { public static void main(String[] args) { // 斷路器被強制打開 ConfigurationManager.getConfigInstance().setProperty( "hystrix.command.default.circuitBreaker.forceOpen", "true"); FallbackCommand c = new FallbackCommand(); c.execute(); // 建立第二個命令,斷路器關閉 ConfigurationManager.getConfigInstance().setProperty( "hystrix.command.default.circuitBreaker.forceOpen", "false"); FallbackCommand c2 = new FallbackCommand(); c2.execute(); } static class FallbackCommand extends HystrixCommand<String> { public FallbackCommand() { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); } /** * 斷路器被強制打開,該方法不會執行 */ protected String run() throws Exception { System.out.println("命令執行"); return ""; } /** * 回退方法,斷路器打開後會執行回退 */ protected String getFallback() { System.out.println("執行回退方法"); return "fallback"; } } }
若是讓斷路器打開,須要符合必定的條件,本例爲了簡單起見,在代碼清單中,使用了配置管理類(ConfigurationManager)將斷路器強制打開與關閉,在打開斷路器後,FallbackCommand總會執行回退(getFallback)方法,將斷路器關閉,命令執行正常。若是斷路器被打開,而命令中沒有提供回退方法,將拋出如下異常:
com.netflix.hystrix.exception.HystrixRuntimeException: FallbackCommand short-circuited and no fallback available.
另外,須要注意的是,命令執行後,無論是否會觸發回退,都會去計算整個鏈路的健康情況,根據健康情況來判斷是否要打開斷路器,若是命令僅僅失敗了一次,是不足以打開斷路器的,關於斷路器的邏輯將在後面章節講述。
Hystrix的回退機制比較靈活,你能夠在A命令的回退方法中執行B命令,若是B命令也執行失敗,一樣也會觸發B命令的回退,這樣就造成一種鏈式的命令執行,例如如下代碼片段:
static class CommandA extends HystrixCommand<String> { …省略其餘代碼 protected String run() throws Exception { throw new RuntimeException(); } protected String getFallback() { return new CommandB().execute(); } }
還有其餘較爲複雜的例子,例如銀行轉帳,假設一個轉帳命令包含調用A銀行扣款、B銀行加款兩個命令,其中一個命令失敗後,再執行轉帳命令的回退,如圖6-4所示。
圖6-4 多命令回退
要作到圖6-4的多命令只執行一次回退的效果,CommandA與CommandB,不能有回退方法,若是CommandA命令執行失敗,而且該命令有回退方法,此時將不會執行「MainCommand」的回退方法。除了上面所提到的鏈式的回退以及多命令回退,讀者還能夠根據實際狀況來設計回退。
本文節選自《瘋狂Spring Cloud微服務架構實戰》
Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993