Hystrix 是 Netflix 針對微服務分布式系統采用的熔斷保護中間件,相當於電路中的保險絲。
在分布式環境中,許多服務依賴項中的一些必然會失敗。Hystrix 是一個庫,通過添加延遲容忍和容錯邏輯,幫助你控制這些分布式服務之間的交互。Hystrix 通過隔離服務之間的訪問點、停止級聯失敗和提供回退選項來實現這一點,所有這些都可以提高系統的整體彈性。
在微服務架構下,很多服務都相互依賴,如果不能對依賴的服務進行隔離,那么服務本身也有可能發生故障,Hystrix 通過 HystrixCommand 對調用進行隔離,這樣可以阻止故障的連鎖效應,能夠讓接口調用快速失敗並迅速恢復正常,或者回退並優雅降級。
Hystrix 的簡單使用
創建一個空的 Maven 項目,在項目中增加 Hystrix 的依賴,代碼如下所示。
<dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.5.18</version> </dependency>
編寫第一個 HystrixCommand,代碼如下所示。
public class MyHystrixCommand extends HystrixCommand<String> { private final String name; public MyHystrixCommand(String name) { super(HystrixCommandGroupKey.Factory.asKey("MyGroup")); this.name = name; } @Override protected String run() { return this.name + ":" + Thread.currentThread().getName(); } }
首先需要繼承 HystrixCommand,通過構造函數設置一個 Groupkey。具體的邏輯在 run 方法中,我們返回了一個當前線程名稱的值。寫一個 main 方法來調用上面編寫的 MyHystrixCommand 程序,代碼如下所示。
public static void main(String[] args) throws InterruptedException, ExecutionException { String result = new MyHystrixCommand("zhangsan").execute(); System.out.println(result); }
輸出結果如圖 1 所示:
從圖 1 中可以看到輸出結果是“zhangsan:hystrix-MyGroup-1”。由此可以看出,構造函數中設置的組名變成了線程的名字。
上面是同步調用,如果需要異步調用可以使用如下代碼所示的方法。
public static void main(String[] args) throws InterruptedException, ExecutionException { Future<String> future = new MyHystrixCommand("zhangsan").queue(); System.out.println(future.get()); }
運行結果和圖 1 相同。
回退支持
下面我們通過增加執行時間模擬調用超時失敗的情況。首先改造 MyHystrixCommand,增加 getFallback 方法返回回退內容,代碼如下所示。
public class MyHystrixCommand extends HystrixCommand<String> { private final String name; public MyHystrixCommand(String name) { super(HystrixCommandGroupKey.Factory.asKey("MyGroup")); this.name = name; } @Override protected String run() { try { Thread.sleep(1000 * 10); } catch (InterruptedException e) { e.printStackTrace(); } return this.name + ":" + Thread.currentThread().getName(); } @Override protected String getFallback() { return "失敗了 "; } }
重新執行調用代碼,運行結果如圖 2 所示,可以發現返回的內容是“失敗了”,證明已經觸發了回退。
圖 2 運行結果