服務保護機制SpringCloud Hystrix
微服務高可用技術
大型複雜的分散式系統中,高可用相關的技術架構非常重要。
高可用架構非常重要的一個環節,就是如何將分散式系統中的各個服務打造成高可用的服務,從而足以應對分散式系統環境中的各種各樣的問題,,避免整個分散式系統被某個服務的故障給拖垮。
比如:
服務間的呼叫超時
服務間的呼叫失敗
要解決這些棘手的分散式系統可用性問題,就涉及到了高可用分散式系統中的很多重要的技術,包括:
資源隔離
限流與過載保護
熔斷
優雅降級
容錯
超時控制
監控運維
服務降級、熔斷、限流概念
服務學崩效應
服務雪崩效應產生與服務堆積在同一個執行緒池中,因為所有的請求都是同一個執行緒池進行處理,這時候如果在高併發情況下,所有的請求全部訪問同一個介面,
這時候可能會導致其他服務沒有執行緒進行接受請求,這就是服務雪崩效應效應。
服務降級
在高併發情況下,防止使用者一直等待,使用服務降級方式(直接返回一個友好的提示給客戶端,呼叫fallBack方法)
服務熔斷
熔斷機制目的為了保護服務,在高併發的情況下,如果請求達到一定極限(可以自己設定闊值)如果流量超出了設定閾值,讓後直接拒絕訪問,保護當前服務。使用服務降級方式返回一個友好提示,服務熔斷和服務降級一起使用
服務隔離
因為預設情況下,只有一個執行緒池會維護所有的服務介面,如果大量的請求訪問同一個介面,達到tomcat 執行緒池預設極限,可能會導致其他服務無法訪問。
解決服務雪崩效應:使用服務隔離機制(執行緒池方式和訊號量),使用執行緒池方式實現隔離的原理: 相當於每個介面(服務)都有自己獨立的執行緒池,因為每個執行緒池互不影響,這樣的話就可以解決服務雪崩效應。
執行緒池隔離:
每個服務介面,都有自己獨立的執行緒池,每個執行緒池互不影響。
訊號量隔離:
使用一個原子計數器(或訊號量)來記錄當前有多少個執行緒在執行,當請求進來時先判斷計數器的數值,若超過設定的最大執行緒個數則拒絕該請求,若不超過則通行,這時候計數器+1,請求返 回成功後計數器-1。
服務限流
服務限流就是對介面訪問進行限制,常用服務限流演算法令牌桶、漏桶。計數器也可以進行粗暴限流實現。
Hystrix簡單介紹
Hystrix是國外知名的視訊網站Netflix所開源的非常流行的高可用架構框架。Hystrix能夠完美的解決分散式系統架構中打造高可用服務面臨的一系列技術難題。
Hystrix “豪豬”,具有自我保護的能力。hystrix 通過如下機制來解決雪崩效應問題。
在微服務架構中,我們把每個業務都拆成了單個服務模組,然後當有業務需求時,服務間可互相呼叫,但是,由於網路原因或者其他一些因素,有可能出現服務不可用的情況,當某個服務出現問題時,其他服務如果繼續呼叫這個服務,就有可能出現執行緒阻塞,但如果同時有大量的請求,就會造成執行緒資源被用完,這樣就可能會導致服務癱瘓,由於服務間會相互呼叫,很容易造成蝴蝶效應導致整個系統宕掉。因此,就有人提出來斷路器來解決這一問題。
資源隔離:包括執行緒池隔離和訊號量隔離,限制呼叫分散式服務的資源使用,某一個呼叫的服務出現問題不會影響其他服務呼叫。
降級機制:超時降級、資源不足時(執行緒或訊號量)降級,降級後可以配合降級介面返回託底資料。
融斷:當失敗率達到閥值自動觸發降級(如因網路故障/超時造成的失敗率高),熔斷器觸發的快速失敗會進行快速恢復。
快取:提供了請求快取、請求合併實現。
Hystrix環境搭建
Maven依賴資訊
<!-- hystrix斷路器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
開啟Hystrix斷路器
application.yml
feign: hystrix: enabled: true #### hystrix禁止服務超時時間 hystrix: command: default: execution: timeout: enabled: false
@SpringBootApplication @EnableEurekaClient @EnableFeignClients @EnableHystrix public class AppOrder { public static void main(String[] args) { SpringApplication.run(AppOrder.class, args); } }
服務降級處理
使用註解方式
@HystrixCommand(fallbackMethod = "orderToUserInfoFallback") @GetMapping("/orderToUserInfo") public ResponseBase orderToUserInfoHystrix() { System.out.println("orderToUserInfo:" + "當前執行緒池名稱:" + Thread.currentThread().getName()); return memberServiceFeigin.getUserInfo(); } @RequestMapping("/orderToUserInfoFallback") public ResponseBase orderToUserInfoFallback() { return setResultError("系統錯誤!!!!"); }
@HystrixCommand預設開啟執行緒池隔離,開啟熔斷,可加服務降級。預設超時時間1秒,可設定關閉
使用類的方式服務降級 -------結合feign -------------實際專案一般採用此方式
@RequestMapping("/orderToUserInfo") public ResponseBase orderToUserInfo() { return memberServiceFeigin.getUserInfo(); } @Component public class MemberServiceFallback extends BaseApiService implements MemberServiceFeigin { public ResponseBase getUserInfo() { // 服務降級處理 return setResultError("系統錯誤,請稍後重試!"); } }