Spring?Cloud?Hystrix的基本用法大全
本文主要講述Hystrix,也可以稱之為豪豬哥。
它是Spring Cloud中集成的一個(gè)組件,在整個(gè)生態(tài)中主要為我們提供以下功能:
- 服務(wù)隔離
服務(wù)隔離主要包括線程池隔離以及信號(hào)量隔離。
- 服務(wù)熔斷
當(dāng)請(qǐng)求持續(xù)失敗的時(shí)候,服務(wù)進(jìn)行熔斷,默認(rèn)熔斷5S,也是就說在這5S內(nèi)的請(qǐng)求一律拒絕。
- 服務(wù)降級(jí)
當(dāng)前請(qǐng)求失敗的時(shí)候,返回降級(jí)的結(jié)果。
1. Hystrix的簡單使用
1.1 服務(wù)降級(jí)
添加依賴
<!-- hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
- 啟動(dòng)類添加注解
@EnableCircuitBreaker //開啟熔斷
- 對(duì)應(yīng)接口加上注解
注解里面相關(guān)的參數(shù)可以至HystrixCommandProperties
類中查找;注解里面也可以不寫相關(guān)內(nèi)容。
fallbackMethod = "fallback"
里面是熔斷方法名。
//HystrixCommandProperties @HystrixCommand( commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10") },fallbackMethod = "fallback") @GetMapping public String order() { log.info("begin do order"); // 使用openfiegn String goods = goodsService.getGoodsById(); String promotion = promotionService.getPromotionById(); String result = orderService.createOrder(goods, promotion); return result; } public String fallback(){ return "觸發(fā)降級(jí)"; }
修改商品服務(wù)的接口,加上超時(shí)時(shí)間,使接口調(diào)用錯(cuò)誤。
@GetMapping("/goods") public String getGoodsById() { try { Thread.sleep(3000); } catch (Exception e){ e.printStackTrace(); } log.info("收到請(qǐng)求,端口為:{}", port); return "返回商品信息"; }
啟動(dòng)項(xiàng)目,調(diào)用接口,看是否可以進(jìn)行服務(wù)降級(jí)。
1.2 服務(wù)熔斷
熔斷的觸發(fā)機(jī)制
在10S內(nèi),超過20次請(qǐng)求,并且失敗率超過50%(默認(rèn)情況)- > 觸發(fā)熔斷
熔斷后經(jīng)過一段時(shí)間等待后又可以繼續(xù)正常訪問。
我們稍微改造下代碼:
@HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //請(qǐng)求閾值 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),//熔斷窗口持續(xù)時(shí)間 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")//錯(cuò)誤比 }, fallbackMethod = "fallback") @GetMapping("/{num}") public String order(@PathVariable("num") int num) { if (num % 2 == 0) { return "正常訪問。"; } log.info("begin do order"); String goods = goodsService.getGoodsById(); String promotion = promotionService.getPromotionById(); String result = orderService.createOrder(goods, promotion); return result; } public String fallback(int num) { return "觸發(fā)降級(jí)"; }
我們來看下上述代碼,首先我們給接口添加了相關(guān)一個(gè)參數(shù),在接口中根據(jù)傳參來執(zhí)行不同的操作,比如參數(shù)為2那就正常返回,如果參數(shù)為1 就執(zhí)行下面的代碼,由于我們加了超時(shí)時(shí)間,所以會(huì)調(diào)用失敗。
注意,我們給接口加了參數(shù)后,服務(wù)降級(jí)的方法也要加上相關(guān)參數(shù),否則會(huì)錯(cuò)誤。
觸發(fā)的相關(guān)機(jī)制都是可以根據(jù)參數(shù)自己修改的,大家測(cè)試的時(shí)候可以將請(qǐng)求閾值設(shè)置小一點(diǎn),方便測(cè)試查看效果。
2. OpenFeign集成Hystrix
以上都是我們直接在客戶端調(diào)用的時(shí)候直接集成Hystrix
來進(jìn)行服務(wù)的保護(hù),那在OpenFeign
中我們?cè)撊绾渭赡兀?/p>
然后我們?cè)趕ervice-api項(xiàng)目中引入相關(guān)依賴:
<!-- hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
然后我們?cè)诒┞督涌诘牡胤絼?chuàng)建相關(guān)回調(diào)實(shí)現(xiàn):
我們首先實(shí)現(xiàn)暴露接口的FeignClient
,然后在實(shí)現(xiàn)的方法中編寫對(duì)應(yīng)的降級(jí)操作即可,這樣當(dāng)發(fā)生調(diào)用失敗的情況,則會(huì)返回降級(jí)的信息。
這里可以使用component
注解將該類交給spring管理,或者通過configuration
注解進(jìn)行處理。
//@Component public class IGoodsServiceFallback implements IGoodsServiceFeignClient { @Override public String getGoodsById() { return "查詢商品信息異常,觸發(fā)降級(jí)保護(hù)機(jī)制。"; } }
編寫完該類后,我們需要至FeignClient
處進(jìn)行相關(guān)配置。
@FeignClient(name = "goods-service", configuration = FeignClientLogConfiguration.class, fallback = IGoodsServiceFallback.class) public interface IGoodsServiceFeignClient extends IGoodsService { }
這里修改完成后,我們就可以至集成服務(wù)修改相關(guān)配置了。
首先在配置文件中開啟feign的熔斷保護(hù)機(jī)制。
#開啟feign的熔斷保護(hù)機(jī)制 feign.hystrix.enabled=true
然后需要將之前的IGoodsServiceFallback
交給spring容器進(jìn)行管理,我這里是使用的configuration
注解進(jìn)行處理的。
@Configuration public class HystrixFallbackConfiguration { @Bean public IGoodsServiceFallback goodsServiceFallback() { return new IGoodsServiceFallback(); } }
以上便是我們的全部配置,這個(gè)時(shí)候我們只需要去goods-service
中的調(diào)用接口人為的制造一些異常,這樣調(diào)用的時(shí)候就可以觸發(fā)異常了。
比如我直接加了超時(shí)時(shí)間:
@Slf4j @RestController public class GoodsService implements IGoodsService { @Value("${server.port}") private String port; /** * 根據(jù)ID查詢商品信息 * * @return */ @GetMapping("/goods") public String getGoodsById() { try { Thread.sleep(5000); } catch (Exception e){ e.printStackTrace(); } log.info("收到請(qǐng)求,端口為:{}", port); return "返回商品信息"; } }
然后我們就可以直接開始測(cè)試了:
可以看到成功獲取了降級(jí)信息,代表我們集成成功。
實(shí)際上我們?cè)谡{(diào)用OpenFeign接口的時(shí)候,他會(huì)判斷我們的Feign接口上是否有Hustrix
的一些機(jī)制,如果有的話先進(jìn)行相關(guān)判斷,然后在執(zhí)行請(qǐng)求。如下圖所示:
3. Hystrix熔斷原理
下圖為Hystrix的熔斷簡單工作原理,調(diào)用出現(xiàn)異常后,如果錯(cuò)誤率達(dá)到一個(gè)閾值,則開始熔斷。相關(guān)的閾值,時(shí)間等都是可以進(jìn)行配置的。
3.1 熔斷狀態(tài)
- open
觸發(fā)熔斷,意味著請(qǐng)求不會(huì)發(fā)送到服務(wù)端,而是直接調(diào)用fallback。
- closed
熔斷關(guān)閉,表示可以正常通信。
- Half-Open
熔斷的自動(dòng)恢復(fù)機(jī)制。通過嘗試的方式,判斷服務(wù)是否正常,然后恢復(fù)到closed 狀態(tài);如果還是異常,則繼續(xù)保持熔斷。
3.2 熔斷的工作原理
使用滑動(dòng)窗口來實(shí)現(xiàn)數(shù)據(jù)的統(tǒng)計(jì)。
可能有人不太了解什么是滑動(dòng)窗口。
我們首先來看下計(jì)數(shù)器的一種實(shí)現(xiàn)方式,類似我們?cè)?0s內(nèi)只能發(fā)送一次短信。比如下圖,限制一分鐘之內(nèi)只能接受100個(gè)請(qǐng)求,但是位于臨界點(diǎn)的時(shí)候,我們可能突然收到200個(gè)請(qǐng)求,所以可能會(huì)導(dǎo)致一些問題。
滑動(dòng)窗口和計(jì)算器是類似的,首先多了一個(gè)滑動(dòng)的步驟,窗口會(huì)隨著時(shí)間往前滑動(dòng)。然后我們的窗口大小是固定的(可以自己設(shè)置),比如下圖我們的窗口大小就是60S,隨著時(shí)間的推進(jìn),窗口向前滑動(dòng),但是會(huì)保證大小不變。
熔斷的閾值就是根據(jù)滑動(dòng)窗口的請(qǐng)求數(shù)以及失敗次數(shù)來進(jìn)行計(jì)算的,從而判斷出是否開啟熔斷。
RxJava 響應(yīng)式編程(類似webflux),實(shí)現(xiàn)事件流的分發(fā)。
既然了解了他的大致原理,我們?cè)賹⑦@部分帶入之前的流程中來看:
我們一個(gè)請(qǐng)求進(jìn)來后,如果該接口聲明了HystrixCommand
注解,首先會(huì)調(diào)用allowRequest
方法去校驗(yàn)當(dāng)前請(qǐng)求是否允許發(fā)生:判斷當(dāng)前是否位于isOpen
狀態(tài),如果是則直接返回服務(wù)降級(jí)的邏輯;如果不是則判斷當(dāng)前時(shí)間窗口的總健康請(qǐng)求數(shù)量是否大于20次(閾值可自行設(shè)置),小于則正常執(zhí)行,如果大于則判斷當(dāng)前滑動(dòng)窗口內(nèi)的錯(cuò)誤請(qǐng)求率是否達(dá)到閾值,從而開啟熔斷狀態(tài)。
滑動(dòng)窗口的數(shù)據(jù)統(tǒng)計(jì)都是通過事件流來實(shí)現(xiàn)的,任務(wù)執(zhí)行結(jié)束后,通過發(fā)布一個(gè)時(shí)間,然后將相關(guān)數(shù)據(jù)更新到當(dāng)前時(shí)間窗口中,老的數(shù)據(jù)則直接丟棄。相關(guān)流程比較復(fù)雜,這里不過多闡述。
4. 代碼地址
到此這篇關(guān)于Spring Cloud Hystrix的基本使用的文章就介紹到這了,更多相關(guān)Spring Cloud Hystrix使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud使用Nacos保存和讀取變量的配置方法
在使用SpringCloud開發(fā)微服務(wù)時(shí),經(jīng)常會(huì)遇到一些比較小的后臺(tái)參數(shù)配置,這些配置不足以單獨(dú)開一張表去存儲(chǔ),而且其他服務(wù)會(huì)讀取該參數(shù),這篇文章主要介紹了SpringCloud使用Nacos保存和讀取變量,需要的朋友可以參考下2022-07-07Java上傳文件進(jìn)度條的實(shí)現(xiàn)方法(附demo源碼下載)
這篇文章主要介紹了Java上傳文件進(jìn)度條的實(shí)現(xiàn)方法,可簡單實(shí)現(xiàn)顯示文件上傳比特?cái)?shù)及進(jìn)度的功能,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2015-12-12SpringBoot啟動(dòng)后立即執(zhí)行的幾種方法小結(jié)
在項(xiàng)目開發(fā)中某些場景必須要用到啟動(dòng)項(xiàng)目后立即執(zhí)行方式的功能,本文主要介紹了SpringBoot啟動(dòng)后立即執(zhí)行的幾種方法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2023-05-05