什麼是Hystrix,Hystrix如何使用 容錯框架Hystrix,SpringCloud將Hystrix整合到Netflix項目中了。它主要用來添加一個延遲的閥值和容錯邏輯。來幫助我們控制分散式系統之間的組件交互。 那麼什麼是延遲閥值呢:就拿下圖中的銷售模塊舉例,在銷售模塊調用會員模塊的時候,會 ...
什麼是Hystrix,Hystrix如何使用
容錯框架Hystrix,SpringCloud將Hystrix整合到Netflix項目中了。它主要用來添加一個延遲的閥值和容錯邏輯。來幫助我們控制分散式系統之間的組件交互。
那麼什麼是延遲閥值呢:就拿下圖中的銷售模塊舉例,在銷售模塊調用會員模塊的時候,會給銷售模塊加上一個延遲,比如說 銷售模塊在限定的時間內沒有接收到會員模塊的響應或者有問題,就會觸發容錯的邏輯。
下麵簡單的介紹下,什麼是Hystrix容錯框架
1. Hystrix 能使你的系統在出現依賴服務失效的時候,通過隔離系統所依賴的服務,防止服務級聯失敗,同時提供失敗回退機制,更優雅地應對失效,並使你的系統能更快地從異常中恢復。
2. Hystrix 能做什麼?
2.1 防止單個依賴耗盡容器(例如 Tomcat)內所有用戶線程
2.2 降低系統負載,對無法及時處理的請求快速失敗(fail fast)而不是排隊
2.3 提供失敗回退,以在必要時讓失效對用戶透明化
2.4 使用隔離機制(例如『艙壁』/『泳道』模式,熔斷器模式等)降低依賴服務對整個系統的影響
2.5 針對系統服務的度量、監控和報警,提供優化以滿足近實時性的要求
2.6 在 Hystrix 絕大部分需要動態調整配置並快速部署到所有應用方面,提供優化以滿足快速恢復的要求
2.7 能保護應用不受依賴服務的整個執行過程中失敗的影響,而不僅僅是網路請求
首先,我們把銷售模塊看作是服務調用者,把會員模塊看作服務提供者。 如果會員模塊請求不到數據,連接資料庫超時。有些網站就會有那種情況,就是如果是請求超時,也不會給用戶一個很好的提示,那麼這個時候 用戶可不管你出了什麼問題,用戶就會一直點,一直刷新 這樣的話,就會發送很多請求到伺服器,銷售模塊就會積壓很多請求,會員模塊就會一直等待資料庫的超時返回,這樣就會導致整個集群都有問題了,服務會被阻塞。
傳統的解決方式: 1. 添加超時機制 2. 人肉運維。。。
還有一種,那就是本章內容要講的:Hystrix 容錯框架 |
|
在銷售模塊調用會員模塊的時候,會給銷售模塊加上一個延遲,比如說 銷售模塊在限定的時間內沒有接收到會員模塊的響應或者有問題,就會觸發容錯的邏輯。 如果銷售模塊與會員模塊多次連接失敗,那麼Hystrix就會觸發它的斷路器,將這個節點的銷售模塊與會員模塊的鏈接全部斷掉,所有的請求過來,都會走那個回退邏輯。(回退邏輯屬於銷售模塊中的一部分,並不是一個新的模塊) 這樣的話,實際上是在保護銷售模塊,它就不用等待超時響應這樣的結果了,就直接的可以返回給客戶,告訴客戶這裡有問題了。這樣做就可以減輕整個集群的負擔了。 |
首先,創建兩個介面後 再將服務跑起來:
@RestController public class MyController {
// 模仿成功返回的介面 @RequestMapping(value="/successHello", method=RequestMethod.GET) public String successHello(){ return "successHello"; }
// 模仿在請求的過程中,出現錯誤的介面 @RequestMapping(value="/errorHello", method=RequestMethod.GET) public String errorHello() throws Exception { Thread.sleep(10000); return "errorHello"; } }
服務開啟之後,我們來創建一個客戶端,對介面進行訪問:
String url_success = "http://localhost:8080/successHello"; HttpGet httpGet = new HttpGet(url_success); CloseableHttpClient httpClient = HttpClients.createDefault(); HttpResponse httpResponse = httpClient.execute(httpGet); String result = EntityUtils.toString(httpResponse.getEntity()); System.out.println(result);
我們再將url換成:http://localhost:8080/errorHello,再執行一下 看效果:
errorHello也是可以正常的返回,只不過因為設置了線程的睡眠,晚了10秒才返回結果,,,上面說的都不是重點,重點是上面與下麵的對比,請繼續向下看:
接下來我們創建一個實現命令類:HelloCommand.java 需繼承 HystrixCommand 類
public class HelloCommand extends HystrixCommand<String>{ protected HelloCommand() { super(HystrixCommandGroupKey.Factory.asKey("TestGroup")); } @Override protected String run() throws Exception { // String url = "http://localhost:8080/successHello"; String url = "http://localhost:8080/errorHello"; HttpGet httpGet = new HttpGet(url); CloseableHttpClient httpClient = HttpClients.createDefault(); HttpResponse httpResponse = httpClient.execute(httpGet); String result = EntityUtils.toString(httpResponse.getEntity()); return result; } }
再修改一下main方法,註意觀察命令類是怎樣使用的:
HelloCommand helloCommand = new HelloCommand(); String result = helloCommand.execute(); System.out.println(result);
如果url使用successHello訪問,那麼就會正常的返回數據,因為這個介面能快速調通,沒有出現連接錯誤等問題:
但是如果使用加了線程睡眠的介面errorHello,結果會是什麼樣的呢,我們來看一下:
我們可以看到,因連接超時報的錯 重點是 no fallback available. 說明瞭,我們沒有配置回退的邏輯,下麵我們就加上這個邏輯,需實現 getFallback 方法:
@Override protected String getFallback() { return "No fallback available."; }
好,我們添加完回退邏輯後,再來執行下main方法,看看還會不會報錯: