您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么理解Spring Cloud Hystrix熔斷”,在日常操作中,相信很多人在怎么理解Spring Cloud Hystrix熔斷問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么理解Spring Cloud Hystrix熔斷”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在一個家庭中有各種各樣的家電,我們假設每個家電都沒有保險絲,一旦有一天某個家電出現短路,造成整個電路短路然后很有可能就把整個家庭的電器及電路給燒壞了。但如果每個家電入口線路都有一個保險絲(斷路器),那么不管那個家電發生短路這個家電的保險絲就會快速熔斷(斷開電路),從而保護了整個電路及電路上其它的家電的正常運行。
軟件行業里面的熔斷機制與這個一致,在整個微服務集群中,由于其中一個或者幾個微服務出現故障或堵塞,若沒有快速的熔斷機制,就會造成整個微服務集群的擁堵最終整個微服務出現雪崩被拖死。熔斷機制的核心機制就是在確保某個微服務出現故障的時候實現快速熔斷(斷路)或者服務降級快速失敗,避免擁堵。從而保證其它業務其它服務的正常運行。
防止單個服務的故障,耗盡整個系統服務的容器(比如tomcat)的線程資源,避免分布式環境里大量級聯失敗。通過第三方客戶端訪問(通常是通過網絡)依賴服務出現失敗、拒絕、超時或短路時執行回退邏輯。
用快速失敗代替排隊(每個依賴服務維護一個小的線程池或信號量,當線程池滿或信號量滿,會立即拒絕服務而不會排隊等待)和優雅的服務降級;當依賴服務失效后又恢復正常,快速恢復。
提供接近實時的監控和警報,從而能夠快速發現故障和修復。監控信息包括請求成功,失敗(客戶端拋出的異常),超時和線程拒絕。如果訪問依賴服務的錯誤百分比超過閾值,斷路器會跳閘,此時服務會在一段時間內停止對特定服務的所有請求。
將所有請求外部系統(或請求依賴服務)封裝到HystrixCommand或HystrixObservableCommand對象中,然后這些請求在一個獨立的線程中執行。使用隔離技術來限制任何一個依賴的失敗對系統的影響。每個依賴服務維護一個小的線程池(或信號量),當線程池滿或信號量滿,會立即拒絕服務而不會排隊等待。
請求熔斷: 當Hystrix Command請求后端服務失敗數量超過一定比例(默認50%), 斷路器會切換到開路狀態(Open). 這時所有請求會直接失敗而不會發送到后端服務. 斷路器保持在開路狀態一段時間后(默認5秒), 自動切換到半開路狀態(HALF-OPEN)。這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN). Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦后端服務不可用, 斷路器會直接切斷請求鏈, 避免發送大量無效請求影響系統吞吐量, 并且斷路器有自我檢測并恢復的能力。
服務降級:Fallback相當于是降級操作. 對于查詢操作, 我們可以實現一個fallback方法, 當請求后端服務出現異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設置的默認值或者來自緩存。
依賴隔離(采用艙壁模式,Docker就是艙壁模式的一種):在Hystrix中, 主要通過線程池來實現資源隔離. 通常在使用的時候我們會根據調用的遠程服務劃分出多個線程池.比如說,一個服務調用另外兩個服務,你如果調用兩個服務都用一個線程池,那么如果一個服務卡在哪里,資源沒被釋放后面的請求又來了,導致后面的請求都卡在哪里等待,導致你依賴的A服務把你卡在哪里,耗盡了資源,也導致了你另外一個B服務也不可用了。這時如果依賴隔離,某一個服務調用A B兩個服務,如果這時我有100個線程可用,我給A服務分配50個,給B服務分配50個,這樣就算A服務掛了,我的B服務依然可以用。
請求緩存:比如一個請求過來請求我userId=1的數據,你后面的請求也過來請求同樣的數據,這時我不會繼續走原來的那條請求鏈路了,而是把第一次請求緩存過了,把第一次的請求結果返回給后面的請求(參考@CacheResult、@CacheKey、@CacheRemove注解)。
請求合并:我依賴于某一個服務,我要調用N次,比如說查數據庫的時候,我發了N條請求發了N條SQL然后拿到一堆結果,這時候我們可以把多個請求合并成一個請求,發送一個查詢多條數據的SQL的請求,這樣我們只需查詢一次數據庫,提升了效率。
在Hystrix 中我們用的比較多的是前三點,后面兩點并不適用于所有業務。
添加 `spring-cloud-starter-hystrix`模塊,實際使用過程中我們使用了Feign后已經包含了Hystrix模塊及Ribbon模塊,不需要單獨引入。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
在啟動類中加入@EnableCircuitBreaker注解,表示允許斷路器。如下代碼所示:
//允許斷路器 @EnableCircuitBreaker public class Application { ... }
在spring cloud 項目中使用 `@SpringCloudApplication` 注解后已經包含了`@EnableCircuitBreaker` 注解及其它微服務注解,看源碼:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
Spring cloud 采用http進行通訊,spring cloud 結合Eureka針對http請求響應操作做了封裝,支持兩種方式,RestTemplate 及 Feign 模式,Feign模式參考其它章節,這里簡單介紹RestTemplate模式。
@Service public class HelloService { @Autowired private RestTemplate restTemplate; //請求熔斷注解,當服務出現問題時候會執行fallbackMetho屬性的名為helloFallBack的方法 @HystrixCommand(fallbackMethod = "helloFallBack") public String helloService() throws ExecutionException, InterruptedException { return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody(); } public String helloFallBack(){ return "error"; } }
這是一個外部服務調用的restTemplate實現,通過 @HystrixCommand(fallbackMethod = "helloFallBack") 標志這個方法開啟熔斷機制, 指定熔斷后服務降級方法為:helloFallBack()。此時若被調用方異常,接下來請求都會進入服務降級實現(回調方法)并快速失敗。@HystrixCommand 也可以指定其它配置:
public @interface HystrixCommand { String groupKey() default ""; String commandKey() default ""; String threadPoolKey() default ""; String fallbackMethod() default ""; HystrixProperty[] commandProperties() default {}; HystrixProperty[] threadPoolProperties() default {}; Class<? extends Throwable>[] ignoreExceptions() default {}; ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER; HystrixException[] raiseHystrixExceptions() default {}; String defaultFallback() default ""; }
讓我們來逐個介紹下@HystrixCommand注解的各個參數:
commandKey:配置全局唯一標識服務的名稱,比如,庫存系統有一個獲取庫存服務,那么就可以為這個服務起一個名字來唯一識別該服務,如果不配置,則默認是@HystrixCommand注解修飾的函數的函數名。
groupKey:一個比較重要的注解,配置全局唯一標識服務分組的名稱,比如,庫存系統就是一個服務分組。通過設置分組,Hystrix會根據組來組織和統計命令的告、儀表盤等信息。Hystrix命令默認的線程劃分也是根據命令組來實現。默認情況下,Hystrix會讓相同組名的命令使用同一個線程池,所以我們需要在創建Hystrix命令時為其指定命令組來實現默認的線程池劃分。此外,Hystrix還提供了通過設置threadPoolKey來對線程池進行設置。建議最好設置該參數,使用threadPoolKey來控制線程池組。
threadPoolKey:對線程池進行設定,細粒度的配置,相當于對單個服務的線程池信息進行設置,也可多個服務設置同一個threadPoolKey構成線程組。
fallbackMethod:@HystrixCommand注解修飾的函數的回調函數,@HystrixCommand修飾的函數必須和這個回調函數定義在同一個類中,因為定義在了同一個類中,所以fackback method可以是public/private均可。
commandProperties:配置該命令的一些參數,如executionIsolationStrategy配置執行隔離策略,默認是使用線程隔離,此處我們配置為THREAD,即線程池隔離。參見:com.netflix.hystrix.HystrixCommandProperties中各個參數的定義。
threadPoolProperties:線程池相關參數設置,具體可以設置哪些參數請見:com.netflix.hystrix.HystrixThreadPoolProperties
ignoreExceptions:調用服務時,除了HystrixBadRequestException之外,其他@HystrixCommand修飾的函數拋出的異常均會被Hystrix認為命令執行失敗而觸發服務降級的處理邏輯(調用fallbackMethod指定的回調函數),所以當需要在命令執行中拋出不觸發降級的異常時來使用它,通過這個參數指定,哪些異常拋出時不觸發降級(不去調用fallbackMethod),而是將異常向上拋出。
observableExecutionMode:定義hystrix observable command的模式;
raiseHystrixExceptions:任何不可忽略的異常都包含在HystrixRuntimeException中;
defaultFallback:默認的回調函數,該函數的函數體不能有入參,返回值類型與@HystrixCommand修飾的函數體的返回值一致。如果指定了fallbackMethod,則fallbackMethod優先級更高。
給個例子:
@HystrixCommand(commandKey = "testCommand", groupKey = "testGroup", threadPoolKey = "testThreadKey", fallbackMethod = "hiConsumerFallBack", ignoreExceptions = {NullPointerException.class}, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "101"), @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"), @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440") } )
到此,關于“怎么理解Spring Cloud Hystrix熔斷”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。