目錄
一、前言
二、熔斷器出現(xiàn)背景
2.1 幾個(gè)核心概念
2.1.1 熔斷
2.1.2 限流
2.1.3 降級(jí)
2.2 為什么會(huì)出現(xiàn)熔斷器
2.3 斷路器介紹
2.3.1 斷路器原理
三、Resilience4j介紹
3.1 Resilience4j概述
3.1.1 Resilience4j是什么
3.1.2 Resilience4j功能特性
3.2 Resilience4j核心組件
3.2.1 Bulkhead
3.3 Resilience4j狀態(tài)機(jī)
3.4 幾種服務(wù)熔斷組件對(duì)比
四、springboot整合Resilience4j
4.1 集成過程
4.1.1 導(dǎo)入依賴
4.1.2 添加配置文件
4.1.3 添加配置類
4.1.4 測(cè)試業(yè)務(wù)
4.1.5 接口測(cè)試
4.2 參數(shù)解讀補(bǔ)充
4.2.1 circuitbreaker常用配置參數(shù)
4.2.2 ratelimiter常用配置參數(shù)
4.2.3 retry常用配置參數(shù)
五、寫在文末
一、前言
當(dāng)微服務(wù)數(shù)量越來(lái)越多之后,保證微服務(wù)自身的高可用性就變得異常重要了,高可用也是服務(wù)治理中的重要一環(huán),在保障高可用解決方案中,服務(wù)的熔斷、限流與降級(jí)可以說是其中非常重要的一種手段。
在Java的微服務(wù)生態(tài)中,對(duì)于服務(wù)保護(hù)組件,像springcloud的Hystrix,springcloud alibaba的Sentinel,以及當(dāng)Hystrix停更之后官方推薦使用的Resilience4j。
二、熔斷器出現(xiàn)背景
很多同學(xué)在學(xué)習(xí)微服務(wù)限流組件時(shí),容易對(duì)熔斷、限流、降級(jí)這幾個(gè)概念混淆,甚至在什么場(chǎng)景下使用哪種保護(hù)措施也缺乏深一定的認(rèn)識(shí),這一點(diǎn)有必要搞清楚。
2.1 幾個(gè)核心概念
關(guān)于熔斷、限流、降級(jí)這幾個(gè)關(guān)鍵詞,做一下詳細(xì)的解釋。
2.1.1 熔斷
熔斷,即Circuit Breaker,熔斷是一種故障處理機(jī)制,用于防止故障在系統(tǒng)中蔓延。
當(dāng)一個(gè)服務(wù)出現(xiàn)故障時(shí),熔斷器會(huì)立即中斷對(duì)該服務(wù)的請(qǐng)求,防止服務(wù)的故障傳播到其他的組件。通過熔斷機(jī)制,系統(tǒng)可以快速發(fā)現(xiàn)問題并做出相應(yīng)的處理,避免系統(tǒng)整體崩潰。
2.1.2 限流
Rate Limiting,限流是一種控制請(qǐng)求流量的機(jī)制,用于保護(hù)系統(tǒng)免受過載的影響。
通過限制請(qǐng)求的頻率或數(shù)量,可以確保系統(tǒng)在處理請(qǐng)求時(shí)不會(huì)超出其承受范圍,限流可有效地平滑系統(tǒng)的負(fù)載,并防止突發(fā)流量對(duì)系統(tǒng)的影響。
2.1.3 降級(jí)
Degradation,降級(jí)是一種在系統(tǒng)負(fù)載過高或出現(xiàn)故障時(shí),臨時(shí)關(guān)閉部分功能或服務(wù),以保證系統(tǒng)整體業(yè)務(wù)的可用性和穩(wěn)定性機(jī)制。
通過降級(jí),可以確保系統(tǒng)在面臨異常情況時(shí)依然能夠正常運(yùn)行,而不是完全崩潰。降級(jí)可以根據(jù)不同情況選擇關(guān)閉不同的服務(wù)或功能,以最大程度地保障系統(tǒng)的核心功能。
在這幾個(gè)概念對(duì)應(yīng)的微服務(wù)治理中,服務(wù)熔斷是基礎(chǔ),同時(shí)也是保護(hù)系統(tǒng)受到意外沖擊最基本也最有效的措施。
2.2 為什么會(huì)出現(xiàn)熔斷器
在微服務(wù)開發(fā)中,當(dāng)微服務(wù)數(shù)量越來(lái)越多的時(shí)候,服務(wù)之間的調(diào)用鏈路也越來(lái)越復(fù)雜,當(dāng)某個(gè)服務(wù)調(diào)用另一個(gè)服務(wù)時(shí),如果服務(wù)提供者出現(xiàn)網(wǎng)絡(luò)超時(shí)或其他故障,過多的請(qǐng)求這時(shí)候都打來(lái)時(shí),不僅會(huì)造成服務(wù)提供者的資源被占用過多出現(xiàn)阻塞,同時(shí)服務(wù)調(diào)用者也會(huì)出現(xiàn)堆積最終造成無(wú)法正常提供服務(wù)。
在這種情況下,就需要一種保護(hù)機(jī)制,通過實(shí)現(xiàn)調(diào)用熔斷,以達(dá)到保護(hù)服務(wù)調(diào)用者的目的。如下圖,A服務(wù)調(diào)用B服務(wù),B服務(wù)調(diào)用C服務(wù),當(dāng)C服務(wù)出現(xiàn)故障或超時(shí)時(shí),大量A服務(wù)調(diào)用請(qǐng)求導(dǎo)致B服務(wù)大量超時(shí),最終導(dǎo)致B服務(wù)出現(xiàn)故障,這種級(jí)聯(lián)的故障蔓延,最終會(huì)導(dǎo)致起始處的服務(wù)被沖垮。
2.3 斷路器介紹
斷路器,也叫熔斷器,英文:CircuitBreaker,CircuitBreaker的目的是保護(hù)分布式系統(tǒng)免受故障和異常,提高系統(tǒng)的可用性和健壯性。
具體來(lái)說,當(dāng)一個(gè)組件或服務(wù)出現(xiàn)故障時(shí),CircuitBreaker會(huì)迅速切換到開放OPEN狀態(tài)(保險(xiǎn)絲跳閘斷電),阻止請(qǐng)求發(fā)送到該組件或服務(wù)從而避免更多的請(qǐng)求發(fā)送到該組件或服務(wù)。這可以減少對(duì)該組件或服務(wù)的負(fù)載,防止該組件或服務(wù)進(jìn)一步崩潰,并使整個(gè)系統(tǒng)能繼續(xù)正常運(yùn)行。同時(shí),CircuitBreaker還可以提高系統(tǒng)的可用性和健壯性,因?yàn)樗梢栽诜植际较到y(tǒng)的各個(gè)組件之間自動(dòng)切換,從而避免單點(diǎn)故障的問題。
2.3.1 斷路器原理
CircuitBreaker的核心原理如下圖:
我們可以用狀態(tài)機(jī)來(lái)實(shí)現(xiàn) Circuit Breaker,它有以下三種狀態(tài):
-
關(guān)閉(Closed)狀態(tài);
-
默認(rèn)情況下Circuit Breaker是關(guān)閉的,此時(shí)允許操作執(zhí)行;
-
Circuit Breaker內(nèi)部記錄著最近失敗的次數(shù),如果對(duì)應(yīng)的操作執(zhí)行失敗,次數(shù)就會(huì)續(xù)一次;
-
如果在某個(gè)時(shí)間段內(nèi),失敗次數(shù)(或者失敗比率)達(dá)到閾值,Circuit Breaker會(huì)轉(zhuǎn)換到開啟(Open)狀態(tài);
-
在開啟狀態(tài)中,CircuitBreaker會(huì)啟用一個(gè)超時(shí)計(jì)時(shí)器,設(shè)這個(gè)計(jì)時(shí)器的目的是給集群相應(yīng)的時(shí)間來(lái)恢復(fù)故障。當(dāng)計(jì)時(shí)器時(shí)間到的時(shí)候,Circuit Breaker會(huì)轉(zhuǎn)換到半開啟(Half-Open)狀態(tài)。
-
-
開啟(Open);
-
在此狀態(tài)下,執(zhí)行對(duì)應(yīng)的操作將會(huì)立即失敗并且立即拋出異常。
-
-
半開啟(Half-Open);
-
在此狀態(tài)下,Circuit Breaker 會(huì)允許執(zhí)行一定數(shù)量的操作,如果所有操作全部成功,Circuit Breaker就會(huì)假定故障已經(jīng)恢復(fù),它就會(huì)轉(zhuǎn)換到關(guān)閉狀態(tài),并且重置失敗次數(shù);
-
如果其中 任意一次 操作失敗了,Circuit Breaker就會(huì)認(rèn)為故障仍然存在,所以它會(huì)轉(zhuǎn)換到開啟狀態(tài)并再次開啟計(jì)時(shí)器(再給系統(tǒng)一些時(shí)間使其從失敗中恢復(fù))。
-
在實(shí)際執(zhí)行過程中,幾個(gè)狀態(tài)的切換流程如下圖:
三、Resilience4j介紹
3.1 Resilience4j概述
上面了詳細(xì)解了CircuitBreaker的原理,可以認(rèn)為CircuitBreaker定義了一套業(yè)務(wù)實(shí)現(xiàn)規(guī)則或規(guī)范,而具體的實(shí)現(xiàn)組件,則是Resilience4j,即CircuitBreaker只是一套規(guī)范接口,落地實(shí)現(xiàn)者是Resilience4j。
git代碼:https://github.com/resilience4j/resilience4j
文檔地址:https://resilience4j.readme.io/
3.1.1 Resilience4j是什么
Resilience4j是一款輕量級(jí),易于使用的容錯(cuò)庫(kù),其靈感來(lái)自于Netflix Hystrix,但是專為Java 8和函數(shù)式編程而設(shè)計(jì)。輕量級(jí),因?yàn)閹?kù)只使用了Vavr,它沒有任何其他外部依賴下。相比之下,Netflix Hystrix對(duì)Archaius具有編譯依賴性,Archaius具有更多的外部庫(kù)依賴性。
-
Resilience4j是一個(gè)輕量級(jí)、易于使用的容錯(cuò)庫(kù),其靈感來(lái)自Netflix Hystrix,但專為Java 8和函數(shù)式編程設(shè)計(jì)。
-
Resilience4j提供高階函數(shù)(decorators)來(lái)增強(qiáng)任何功能接口、lambda表達(dá)式或方法引用,包括斷路器、速率限制器、重試或艙壁??梢栽谌魏魏瘮?shù)接口、lambda表達(dá)式或方法引用上使用多個(gè)裝飾器。
-
circuitbreaker組件實(shí)現(xiàn)了斷路器功能,是基于內(nèi)存的斷路器,采用ConcurrentHashMap來(lái)實(shí)現(xiàn)。
3.1.2 Resilience4j功能特性
-
斷路器(Circuit Breaker):在服務(wù)出現(xiàn)故障時(shí)自動(dòng)熔斷,防止請(qǐng)求繼續(xù)失敗導(dǎo)致雪崩效應(yīng)。
-
限流(Rate Limiter):限制請(qǐng)求的并發(fā)數(shù)或速率,防止系統(tǒng)被過載。
-
重試(Retry):在請(qǐng)求失敗時(shí)自動(dòng)重試一定次數(shù),增加系統(tǒng)的可靠性。
-
超時(shí)(Timeout):設(shè)置請(qǐng)求的最大執(zhí)行時(shí)間,防止請(qǐng)求長(zhǎng)時(shí)間阻塞。
-
Bulkhead:通過限制同時(shí)執(zhí)行的請(qǐng)求數(shù)量,保護(hù)系統(tǒng)的部分資源不被耗盡。
使用Resilience4j可以通過簡(jiǎn)單的注解或者編程方式來(lái)實(shí)現(xiàn)以上功能,從而保護(hù)應(yīng)用程序免受故障的影響,幫助應(yīng)用程序在面對(duì)故障和不穩(wěn)定性時(shí)保持穩(wěn)定性和可靠性。
3.2 Resilience4j核心組件
要使用Resilience4j,不需要引入所有依賴,只需要選擇你需要的,Resilience4j提供了以下的核心模塊和拓展模塊:
組件名稱 | 功能 |
---|---|
resilience4j-circuitbreaker | Circuit breaking(熔斷器) |
resilience4j-ratelimiter | Rate limiting(限流器) |
resilience4j-bulkhead | Bulkheading(隔離器)--依賴隔離&負(fù)載保護(hù) |
resilience4j-retry | Automatic retrying (sync and async)(重試、同步&異步) |
resilience4j-cache | Result caching(緩存) |
resilience4j-timelimiter | Timeout handling(超時(shí)處理) |
3.2.1 Bulkhead
Bulkhead,即并發(fā)控制器(艙壁,Bulkhead),是用來(lái)控制并行(parallel)調(diào)用的次數(shù)。Resilience4j提供了兩種艙壁模式的實(shí)現(xiàn),可用于限制并發(fā)執(zhí)行的次數(shù):
-
SemaphoreBulkhead(信號(hào)量艙壁,默認(rèn)),基于Java并發(fā)庫(kù)中的Semaphore實(shí)現(xiàn);
-
FixedThreadPoolBulkhead(固定 線程池艙壁),它使用一個(gè)有界隊(duì)列和一個(gè)固定線程池。
由于基于信號(hào)量的Bulkhead能很好地在多線程和I/O模型下工作,所以選擇介紹基于信號(hào)量的Bulkhead的使用。
3.3 Resilience4j狀態(tài)機(jī)
Resilience4j是CircuitBreaker的具體實(shí)現(xiàn),因此具備CircuitBreaker涉及到熔斷的所有狀態(tài),在Resilience4j中,共有6種狀態(tài),在實(shí)際工作中就是在這6種狀態(tài)之間轉(zhuǎn)換。
-
CLOSED: 關(guān)閉狀態(tài),代表正常情況下的狀態(tài),允許所有請(qǐng)求通過,能通過狀態(tài)轉(zhuǎn)換為OPEN;
-
HALF_OPEN: 半開狀態(tài),即允許一部分請(qǐng)求通過,能通過狀態(tài)轉(zhuǎn)換為CLOSED和OPEN;
-
OPEN: 熔斷狀態(tài),即不允許請(qǐng)求通過,能通過狀態(tài)轉(zhuǎn)為為HALF_OPEN;
-
DISABLED: 禁用狀態(tài),即允許所有請(qǐng)求通過,出現(xiàn)失敗率達(dá)到給定的閾值也不會(huì)熔斷,不會(huì)發(fā)生狀態(tài)轉(zhuǎn)換。
-
METRICS_ONLY: 和DISABLED狀態(tài)一樣,也允許所有請(qǐng)求通過不會(huì)發(fā)生熔斷,但是會(huì)記錄失敗率等信息,不會(huì)發(fā)生狀態(tài)轉(zhuǎn)換。
-
FORCED_OPEN: 與DISABLED狀態(tài)正好相反,啟用CircuitBreaker,但是不允許任何請(qǐng)求通過,不會(huì)發(fā)生狀態(tài)轉(zhuǎn)換。
下面再對(duì)closed、open和half_open 這三種狀態(tài)的切換做下補(bǔ)充:
-
closed -> open : 關(guān)閉狀態(tài)到熔斷狀態(tài),當(dāng)失敗的調(diào)用率(比如超時(shí)、異常等)默認(rèn)50%,達(dá)到一定的閾值服務(wù)轉(zhuǎn)為open狀態(tài),在open狀態(tài)下,所有的請(qǐng)求都被攔截;
-
open-> half_open: 當(dāng)經(jīng)過一定的時(shí)間后,CircubitBreaker中默認(rèn)為60s服務(wù)調(diào)用者允許一定的請(qǐng)求到達(dá)服務(wù)提供者;
-
half_open -> open: 當(dāng)half_open狀態(tài)的調(diào)用失敗率超過給定的閾值,轉(zhuǎn)為open狀態(tài);
-
half_open -> closed: 失敗率低于給定的閾值則默認(rèn)轉(zhuǎn)換為closed狀態(tài);
3.4 幾種服務(wù)熔斷組件對(duì)比
常用的服務(wù)熔斷,服務(wù)降級(jí)框架主要有Spring Cloud Hystrix、Spring Cloud Alibaba Sentinel、resilience4j,下面通過幾個(gè)維度綜合對(duì)比一下各自的特點(diǎn),便于加深對(duì)各種組件的認(rèn)識(shí)。
對(duì)比項(xiàng) | Sentinel | Hystrix | Resilience4j |
---|---|---|---|
開源 | Apache-2.0 license | Apache-2.0 license | Apache-2.0 license |
更新 | 更新頻繁(latest:2.1.1, Aug 8th 2022) | 已停更 | 更新較慢(latest:1.7.1, Jun 25th 2021) |
特點(diǎn) | 輕量級(jí),核心庫(kù)無(wú)多余依賴,性能損耗小 | --- | 基于Java8和函數(shù)式編程,輕量級(jí)容錯(cuò)庫(kù),無(wú)多余依賴 |
隔離策略 | 信號(hào)量隔離 | 信號(hào)量/線程池隔離 | 信號(hào)量隔離 |
熔斷降級(jí)策略 | 異常比率/響應(yīng)時(shí)間/異常數(shù) | 異常比率 | 異常比率/響應(yīng)時(shí)間 |
控制臺(tái) | 實(shí)時(shí)監(jiān)控、機(jī)器發(fā)現(xiàn)、規(guī)則管理等能力。 | 提供監(jiān)控查看 | 不提供 |
系統(tǒng)自適應(yīng) | 支持,結(jié)合應(yīng)用的機(jī)器負(fù)載、CPU 使用率,整體平均響應(yīng)時(shí)間、入口 QPS 和 并發(fā)線程數(shù)等維度進(jìn)行限流操做 | 不支持 | 不支持 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于QPS、調(diào)用關(guān)系的限流 | 有限的支持 | 支持簡(jiǎn)單的Rtate Limiter模式 |
系統(tǒng)自適應(yīng)
結(jié)合應(yīng)用的機(jī)器負(fù)載、CPU 使用率,整體平均響應(yīng)時(shí)間、入口QPS和并發(fā)線程數(shù)等幾個(gè)維度的監(jiān)控指標(biāo)從而決定是否調(diào)用進(jìn)行限流操做
四、springboot整合Resilience4j
上面詳細(xì)介紹了Resilience4j的理論,接下來(lái)通過案例來(lái)看下如何在代碼中集成并使用Resilience4j。
4.1 集成過程
4.1.1 導(dǎo)入依賴
Resilience4j與springboot整合提供了兩個(gè)版本的依賴包,springboot2的版本和springboot3的版本,其中sptingboot2的版本java8就可以支持,本文選擇sptingboot2的版本依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-all</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.7.0</version>
</dependency>
4.1.2 添加配置文件
基本上Resilience4j的核心功能都可以在配置文件中通過官方提供的各種配置去完成,參考下面的配置信息,結(jié)合里面的注釋加深對(duì)配置項(xiàng)的理解。
resilience4j.circuitbreaker:
instances:
backendA:
registerHealthIndicator: true # 是否啟用健康檢查
slidingWindowSize: 10 #用于計(jì)算失敗率的滑動(dòng)窗口大小為10,即最近10次調(diào)用失敗的情況會(huì)被考慮進(jìn)去
permittedNumberOfCallsInHalfOpenState: 3 # 斷路器半開時(shí)允許最大的請(qǐng)求次數(shù)
slidingWindowType: TIME_BASED #配置用于在CircuitBreaker關(guān)閉時(shí)記錄調(diào)用結(jié)果的滑動(dòng)窗口類型。 滑動(dòng)窗口可以是基于計(jì)數(shù)或基于時(shí)間的。
minimumNumberOfCalls: 5 # 熔斷器開始計(jì)算失敗率之前,至少需要的調(diào)用次數(shù)為5次
waitDurationInOpenState: 5s # 斷路器打開后,嘗試等待5秒進(jìn)入半開狀態(tài)
failureRateThreshold: 20 # 當(dāng)失敗率達(dá)到20%時(shí),斷路器會(huì)打開,組織進(jìn)一步的調(diào)用
eventConsumerBufferSize: 10 #用于存儲(chǔ)斷路器相關(guān)事件的緩沖區(qū)大小為10,這些事件可用于被監(jiān)控
#重試策略相關(guān)的配置
resilience4j.retry:
instances:
backendA:
maxAttempts: 3 #最大重試次數(shù)
waitDuration: 2s #每次重試的時(shí)候間隔的等待時(shí)間
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
retryExceptions:
- java.lang.Exception
resilience4j.bulkhead:
instances:
backendA:
maxConcurrentCalls: 10
resilience4j.thread-pool-bulkhead:
instances:
backendC:
maxThreadPoolSize: 11 #配置最大線程池大小
coreThreadPoolSize: 1 #配置核心線程池大小
queueCapacity: 1 #配置隊(duì)列的容量
#限流的配置
resilience4j.ratelimiter:
instances:
backendA: # 限流器的名字
limitForPeriod: 1 # 一個(gè)限制周期內(nèi)可訪問次數(shù)
limitRefreshPeriod: 1s # 限制周期,每個(gè)周期之后,速率限制器將重置回limitForPeriod值
timeoutDuration: 10ms # 線程等待允許執(zhí)行時(shí)間
registerHealthIndicator: true
eventConsumerBufferSize: 100
server:
port: 8081
4.1.3 添加配置類
自定義配置類,將配置文件中配置的每一種熔斷器對(duì)應(yīng)的項(xiàng)注冊(cè)到spring的bean容器中,比如在配置文件中有一個(gè)實(shí)例名稱為backendA;
import io.github.resilience4j.common.circuitbreaker.configuration.CircuitBreakerConfigCustomizer;
import io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigCustomizer;
import org.springframework.context.annotation.Bean;
public class ResilienceConfig {
@Bean
public CircuitBreakerConfigCustomizer circuitBreakerConfigCustomizer() {
return CircuitBreakerConfigCustomizer
.of("backendA", builder -> builder.slidingWindowSize(10));
}
@Bean
public RateLimiterConfigCustomizer rateLimiterConfigCustomizer() {
return RateLimiterConfigCustomizer
.of("backendA", builder -> builder.limitForPeriod(1));
}
}
4.1.4 測(cè)試業(yè)務(wù)
在這里我們測(cè)試兩個(gè)場(chǎng)景,第一個(gè)場(chǎng)景為重試,第二個(gè)場(chǎng)景為限流,對(duì)于下面的兩個(gè)方法做如下的補(bǔ)充說明:
-
@CircuitBreaker,該注解里面有兩個(gè)屬性,name和fallbackMethod;
-
name,即配置文件中配置的那個(gè)實(shí)例名稱;
-
fallbackMethod,出現(xiàn)錯(cuò)誤時(shí)使用哪個(gè)降級(jí)方法;
-
-
@Retry,與@CircuitBreaker注解相同,也是兩個(gè)相同的屬性,具有類似的含義;
-
一般來(lái)說,@CircuitBreaker注解和@Retry可以搭配使用,也可以單獨(dú)使用@Retry;
-
import com.congge.entity.User;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.retry.annotation.Retry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
@Service
public class UserService {
private Logger logger = LoggerFactory.getLogger(UserService.class);
@CircuitBreaker(name = "backendA")
@Retry(name = "backendA")
// @RateLimiter(name = "backendA", fallbackMethod = "fallback")
public User retry() {
logger.info("backendA findUser");
String res = new RestTemplate().getForObject("http://localhost:8088", String.class);
if (Objects.nonNull(res)) {
return new User("remote user", 18, "Man");
}
return new User("default user", 22, "Woman");
}
@CircuitBreaker(name = "backendA")
@RateLimiter(name = "backendA",fallbackMethod = "fallback")
public User limit() {
return new User("remote user", 18, "Man");
}
public User fallback(Throwable e) {
return new User("降級(jí)的用戶", 18, "D");
}
}
控制器類用于測(cè)試使用
@RestController
public class UserController {
@Resource
private UserService userService;
@GetMapping("/retry")
public User retry() {
return userService.retry();
}
@GetMapping("/limit")
public User limit() {
return userService.limit();
}
}
4.1.5 接口測(cè)試
重試功能測(cè)試,在第一個(gè)方法中,遠(yuǎn)程調(diào)用一個(gè)不存在的鏈接,理論上會(huì)失敗,按照參數(shù)配置,調(diào)用失敗后,會(huì)重試3次,如果3次之后仍然失敗,則接口拋出異常(或使用降級(jí)的方法的返回結(jié)果)。
重試接口測(cè)試
接口經(jīng)過一段時(shí)間之后失敗
同時(shí)查看控制臺(tái)日志輸出,不難發(fā)現(xiàn),重試了3次,3次時(shí)候輸出了異常的堆棧信息。
限流接口測(cè)試
調(diào)用限流接口,在配置文件中默認(rèn)的是每秒允許通過一個(gè)請(qǐng)求,當(dāng)我們正常請(qǐng)求接口時(shí),可以正常得到結(jié)果。
快速刷接口時(shí),由于方法中添加了降級(jí)方法,將會(huì)得到降級(jí)的響應(yīng)結(jié)果。
4.2 參數(shù)解讀補(bǔ)充
通過上面的案例演示了使用Resilience4j進(jìn)行接口的重試或限流操作,只需配置好核心的參數(shù),并且在方法上添加相關(guān)的注解即可。
在實(shí)際開發(fā)中,對(duì)Resilience4j的使用,也是重點(diǎn)落在對(duì)配置文件中3個(gè)模塊配置參數(shù)的調(diào)整,了解這些配置參數(shù)的具體含義才能結(jié)合實(shí)際場(chǎng)景合理使用,具體來(lái)說,主要是下面幾部分:
-
circuitbreaker,斷路器配置;
-
retry,重試配置;
-
ratelimiter,限流配置;
4.2.1 circuitbreaker常用配置參數(shù)
circuitbreaker的常用可配置參數(shù)項(xiàng)如下
配置參數(shù) | 默認(rèn)值 | 描述 |
---|---|---|
failureRateThreshold | 50 | 熔斷器關(guān)閉狀態(tài)和半開狀態(tài)使用的同一個(gè)失敗率閾值 |
ringBufferSizeInHalfOpenState | 10 | 熔斷器半開狀態(tài)的緩沖區(qū)大小,會(huì)限制線程的并發(fā)量,例如緩沖區(qū)為10則每次只會(huì)允許10個(gè)請(qǐng)求調(diào)用后端服務(wù) |
ringBufferSizeInClosedState | 100 | 熔斷器關(guān)閉狀態(tài)的緩沖區(qū)大小,不會(huì)限制線程的并發(fā)量,在熔斷器發(fā)生狀態(tài)轉(zhuǎn)換前所有請(qǐng)求都會(huì)調(diào)用后端服務(wù) |
waitDurationInOpenState | 60(s) | 熔斷器從打開狀態(tài)轉(zhuǎn)變?yōu)榘腴_狀態(tài)等待的時(shí)間 |
automaticTransitionFromOpenToHalfOpenEnabled | false | 如果置為true,當(dāng)?shù)却龝r(shí)間結(jié)束會(huì)自動(dòng)由打開變?yōu)榘腴_,若置為false,則需要一個(gè)請(qǐng)求進(jìn)入來(lái)觸發(fā)熔斷器狀態(tài)轉(zhuǎn)換 |
recordExceptions | empty | 需要記錄為失敗的異常列表 |
ignoreExceptions | empty | 需要忽略的異常列表 |
recordFailure | throwable -> true | 自定義的謂詞邏輯用于判斷異常是否需要記錄或者需要忽略,默認(rèn)所有異常都進(jìn)行記錄 |
slowCallRateThreshold | 100 | 以百分比配置閾值。當(dāng)呼叫持續(xù)時(shí)間大于等于或大于閾值時(shí),CircuitBreaker 將呼叫視為慢速呼叫。 當(dāng)慢速呼叫的百分比等于或大于閾值時(shí),CircuitBreaker 轉(zhuǎn)換為打開并開始短路呼叫 |
slowCallDurationThreshold | 60000(ms) | 配置持續(xù)時(shí)間閾值,超過該閾值呼叫被視為慢速并提高慢速呼叫率。 |
permittedNumberOfCallsInHalfOpenState | 10 | 配置 CircuitBreaker 半開時(shí)允許的調(diào)用次數(shù)。 |
maxWaitDurationInHalfOpenState | 100 | 配置在 CircuitBreaker 計(jì)算錯(cuò)誤率或慢速調(diào)用率之前所需的最小調(diào)用次數(shù)(每個(gè)滑動(dòng)窗口周期)。 |
waitDurationInOpenState | 100 | 斷路器在從打開轉(zhuǎn)換為半打開之前應(yīng)等待的時(shí)間 |
slidingWindowSize | 100 | 如果滑動(dòng)窗口是 COUNT_BASED,則記錄并匯總最后一次調(diào)用。 如果滑動(dòng)窗口是TIME_BASED,則記錄并匯總最后幾秒的調(diào)用。slidingWindowSize配置用于在 CircuitBreaker 關(guān)閉時(shí)記錄調(diào)用結(jié)果的滑動(dòng)窗口的大小。 |
slidingWindowType | COUNT_BASED | 配置用于在CircuitBreaker關(guān)閉時(shí)記錄調(diào)用結(jié)果的滑動(dòng)窗口類型。 滑動(dòng)窗口可以是基于計(jì)數(shù)或基于時(shí)間的。 |
4.2.2 ratelimiter常用配置參數(shù)
ratelimiter的常用可配置參數(shù)項(xiàng)如下
配置參數(shù) | 默認(rèn)值 | 描述 |
---|---|---|
timeoutDuration | 5s | 線程等待權(quán)限的默認(rèn)等待時(shí)間 |
limitRefreshPeriod | 500ms | 權(quán)限刷新的時(shí)間,每個(gè)周期結(jié)束后,RateLimiter將會(huì)把權(quán)限計(jì)數(shù)設(shè)置為limitForPeriod的值 |
limiteForPeriod | 一個(gè)限制刷新期間的可用權(quán)限數(shù) |
4.2.3 retry常用配置參數(shù)
retry的常用可配置參數(shù)項(xiàng)如下文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-838601.html
配置參數(shù) | 默認(rèn)值 | 描述 |
---|---|---|
maxAttempts | 3 | 最大重試次數(shù) |
waitDuration | 500ms | 固定重試間隔 |
intervalFunction | numberOfAttempts -> waitDuration | 用來(lái)改變重試時(shí)間間隔,可以選擇指數(shù)退避或者隨機(jī)時(shí)間間隔 |
retryOnResultPredicate | result -> false | 自定義結(jié)果重試規(guī)則,需要重試的返回true |
retryOnExceptionPredicate | throwable -> true | 自定義異常重試規(guī)則,需要重試的返回true |
retryExceptions | empty | 需要重試的異常列表 |
ignoreExceptions | empty | 需要忽略的異常列表 |
五、寫在文末
熔斷、限流與降級(jí)作為微服務(wù)治理中的重要一環(huán),有必要對(duì)其引起重視和關(guān)注,而Resilience4j吸收了主流熔斷器的優(yōu)勢(shì),具備更為靈活的特點(diǎn),適用于普通的springboot項(xiàng)目,也能很方便的集成到微服務(wù)框架中,值得深入的學(xué)習(xí)和研究。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-838601.html
到了這里,關(guān)于【微服務(wù)】SpringBoot整合Resilience4j使用詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!