成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Resilience4j使用指南

Labradors / 2836人閱讀

摘要:以下是它的示例現(xiàn)在,如果需要的話,所有對(duì)已修飾的服務(wù)塊的調(diào)用都要符合速率限制器配置。

案例概述

在本文中,我們討論一下Resilience4j庫。
該庫通過管理遠(yuǎn)程通信的容錯(cuò)性來幫助實(shí)現(xiàn)彈性系統(tǒng)。
這個(gè)庫受到Hystrix的啟發(fā),但提供了更方便的API和許多其他特性,如速率限制器(阻塞太頻繁的請(qǐng)求)、Bulkhead(避免太多并發(fā)請(qǐng)求)等。

Maven設(shè)置

首先,我們需要將目標(biāo)模塊添加到我們的pom.xml中(例如,我們添加了Circuit Breaker):


????io.github.resilience4j
????resilience4j-circuitbreaker
????0.12.1

在這里,我們使用的是斷路器模塊。所有模塊及其最新版本均可在Maven Central上找到。
在接下來的部分中,我們將介紹庫中最常用的模塊。

斷路器

請(qǐng)注意,對(duì)于此模塊,我們需要上面顯示的設(shè)置resilience4j-circuitbreaker依賴項(xiàng)。

斷路器模式可以幫助我們?cè)谶h(yuǎn)程服務(wù)中斷時(shí)防止一連串的故障。

在多次失敗的嘗試之后,我們可以認(rèn)為服務(wù)不可用/重載,并急切地拒絕所有后續(xù)的請(qǐng)求。通過這種方式,我們可以為可能失敗的調(diào)用節(jié)省系統(tǒng)資源。

讓我們看看我們?nèi)绾瓮ㄟ^Resilience4j實(shí)現(xiàn)這一目標(biāo)。

首先,我們需要定義要使用的設(shè)置。最簡(jiǎn)單的方法是使用默認(rèn)設(shè)置:

CircuitBreakerRegistry circuitBreakerRegistry
??= CircuitBreakerRegistry.ofDefaults();

也可以使用自定義參數(shù):

CircuitBreakerConfig config = CircuitBreakerConfig.custom()
??.failureRateThreshold(20)
??.ringBufferSizeInClosedState(5)
??.build();

在這里,我們將速率閾值設(shè)置為20%,并將嘗試呼叫設(shè)置為最少5次。

然后,我們創(chuàng)建一個(gè)CircuitBreaker對(duì)象并通過它調(diào)用遠(yuǎn)程服務(wù):

interface RemoteService {
????int process(int i);
}
?
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("my");
Function decorated = CircuitBreaker
??.decorateFunction(circuitBreaker, service::process);

最后,讓我們通過JUnit測(cè)試看看它是如何工作的。

我們將嘗試調(diào)用服務(wù)10次。我們應(yīng)該能夠驗(yàn)證該呼叫至少嘗試了5次,然后在20%的呼叫失敗后停止:

when(service.process(any(Integer.class))).thenThrow(new RuntimeException());
?
for (int i = 0; i < 10; i++) {
????try {
????????decorated.apply(i);
????} catch (Exception ignore) {}
}
?
verify(service, times(5)).process(any(Integer.class));
斷路器的狀態(tài)和設(shè)置

斷路器可以處于以下三種狀態(tài)之一:

CLOSED - 一切正常,不涉及短路

OPEN - 遠(yuǎn)程服務(wù)器已關(guān)閉,所有請(qǐng)求都被短路

HALF_OPEN - 從進(jìn)入開放狀態(tài)到現(xiàn)在已經(jīng)經(jīng)過了一段時(shí)間,斷路器允許請(qǐng)求檢查遠(yuǎn)程服務(wù)是否重新上線

我們可以配置以下設(shè)置:

斷路器打開并開始短路呼叫的故障率閾值

等待時(shí)間,它定義了斷路器在切換到半開狀態(tài)之前應(yīng)該保持打開狀態(tài)的時(shí)間

斷路器半開或半閉時(shí)環(huán)形緩沖器的尺寸

處理斷路器事件的定制電路斷路器事件監(jiān)聽器

一個(gè)自定義謂詞,用于評(píng)估異常是否應(yīng)算作故障,從而提高故障率

速率限制器

與上一節(jié)類似,此功能需要resilience4j-ratelimiter依賴項(xiàng)。

顧名思義,此功能允許限制對(duì)某些服務(wù)的訪問。它的API與CircuitBreaker非常相似- 有Registry,Config和Limiter類。

以下是它的示例:

RateLimiterConfig config = RateLimiterConfig.custom().limitForPeriod(2).build();
RateLimiterRegistry registry = RateLimiterRegistry.of(config);
RateLimiter rateLimiter = registry.rateLimiter("my");
Function decorated
??= RateLimiter.decorateFunction(rateLimiter, service::process);

現(xiàn)在,如果需要的話,所有對(duì)已修飾的服務(wù)塊的調(diào)用都要符合速率限制器配置。

我們可以配置如下參數(shù):

限制刷新的時(shí)間段

刷新周期的權(quán)限限制

默認(rèn)等待權(quán)限持續(xù)時(shí)間

Bulkhead

在這里,我們首先需要relasticience4j-bulkhead依賴項(xiàng)。

可以限制對(duì)特定服務(wù)的并發(fā)調(diào)用數(shù)。

讓我們看一個(gè)使用Bulkhead API配置最多一個(gè)并發(fā)調(diào)用的示例:

BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(1).build();
BulkheadRegistry registry = BulkheadRegistry.of(config);
Bulkhead bulkhead = registry.bulkhead("my");
Function decorated
??= Bulkhead.decorateFunction(bulkhead, service::process);

要測(cè)試此配置,我們將調(diào)用模擬服務(wù)的方法。

然后,我們確保Bulkhead不允許任何其他調(diào)用:

CountDownLatch latch = new CountDownLatch(1);
when(service.process(anyInt())).thenAnswer(invocation -> {
????latch.countDown();
????Thread.currentThread().join();
????return null;
});
?
ForkJoinTask task = ForkJoinPool.commonPool().submit(() -> {
????try {
????????decorated.apply(1);
????} finally {
????????bulkhead.onComplete();
????}
});
latch.await();
assertThat(bulkhead.isCallPermitted()).isFalse();

我們可以配置以下設(shè)置:

Bulkhead允許的最大并行執(zhí)行量

嘗試進(jìn)入飽和艙壁時(shí)線程等待的最長時(shí)間

重試

對(duì)于此功能,我們需要將resilience4j-retry庫添加到項(xiàng)目中。

我們可以使用Retry API 自動(dòng)重試失敗的呼叫

RetryConfig config = RetryConfig.custom().maxAttempts(2).build();
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry("my");
Function decorated
??= Retry.decorateFunction(retry, (Integer s) -> {
????????service.process(s);
????????return null;
????});

現(xiàn)在讓我們模擬在遠(yuǎn)程服務(wù)調(diào)用期間拋出異常的情況,并確保庫自動(dòng)重試失敗的調(diào)用:

when(service.process(anyInt())).thenThrow(new RuntimeException());
try {
????decorated.apply(1);
????fail("Expected an exception to be thrown if all retries failed");
} catch (Exception e) {
????verify(service, times(2)).process(any(Integer.class));
}

我們還可以配置以下內(nèi)容:

最大嘗試次數(shù)

重試前的等待時(shí)間

自定義函數(shù),用于修改失敗后的等待間隔

自定義謂詞,用于評(píng)估異常是否應(yīng)導(dǎo)致重試調(diào)用

緩存

Cache模塊需要resilience4j-cache依賴項(xiàng)。

初始化看起來與其他模塊略有不同:

javax.cache.Cache cache = ...; // Use appropriate cache here
Cache cacheContext = Cache.of(cache);
Function decorated
??= Cache.decorateSupplier(cacheContext, () -> service.process(1));

這里的緩存是通過使用JSR-107 Cache實(shí)現(xiàn)完成的,Resilience4j提供了一種應(yīng)用它的方法。

請(qǐng)注意,沒有用于裝飾功能的API(如Cache.decorateFunction(Function)),API僅支持 Supplier和Callable類型。

TimeLimiter

對(duì)于此模塊,我們必須添加resilience4j-timelimiter依賴項(xiàng)。
可以使用TimeLimiter限制調(diào)用遠(yuǎn)程服務(wù)所花費(fèi)的時(shí)間。
為了演示,讓我們?cè)O(shè)置一個(gè)配置超時(shí)為1毫秒的TimeLimiter:

long ttl = 1;
TimeLimiterConfig config
??= TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(ttl)).build();
TimeLimiter timeLimiter = TimeLimiter.of(config);

接下來,讓我們驗(yàn)證Resilience4j是否使用預(yù)期的超時(shí)調(diào)用Future.get():

Future futureMock = mock(Future.class);
Callable restrictedCall
??= TimeLimiter.decorateFutureSupplier(timeLimiter, () -> futureMock);
restrictedCall.call();
?
verify(futureMock).get(ttl, TimeUnit.MILLISECONDS);

我們也可以將它與CircuitBreaker結(jié)合使用:

Callable chainedCallable
??= CircuitBreaker.decorateCallable(circuitBreaker, restrictedCall);
附加模塊

Resilience4j還提供了許多附加模塊,可以簡(jiǎn)化與流行框架和庫的集成。

一些比較知名的集成是:

Spring Boot – resilience4j-spring-boot

Ratpack – resilience4j-ratpack

Retrofit – resilience4j-retrofit

Vertx – resilience4j-vertx

Dropwizard – resilience4j-metrics

Prometheus – resilience4j-prometheus

案例結(jié)論

在本文中,我們了解了Resilience4j庫的各個(gè)方面,并學(xué)習(xí)了如何使用它來解決服務(wù)器間通信中的各種容錯(cuò)問題。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73168.html

相關(guān)文章

  • Java 項(xiàng)目中使用 Resilience4j 實(shí)現(xiàn)客戶端 API 調(diào)用的限速/節(jié)流機(jī)制

    摘要:客戶端限速作為服務(wù)的消費(fèi)者,我們希望確保我們不會(huì)使服務(wù)提供者過載。調(diào)優(yōu)客戶端和服務(wù)器端速率限制器實(shí)現(xiàn)客戶端速率限制并不能保證我們永遠(yuǎn)不會(huì)受到上游服務(wù)的速率限制。 在本系列的上一篇文章中,我們了解了 Resilience4j 以及如何使用其 Retry 模塊?,F(xiàn)在讓我們了解 RateLimiter - 它是什么,...

    番茄西紅柿 評(píng)論0 收藏2637
  • SpringCloud升級(jí)之路2020.0.x版-40. spock 單元測(cè)試封裝的 WebClie

    摘要:在上面打開一個(gè)微服務(wù)某個(gè)實(shí)例的一個(gè)路徑的斷路器之后,我們調(diào)用其他的路徑,無論多少次,都成功并且調(diào)用負(fù)載均衡器獲取服務(wù)實(shí)例的次數(shù)等于調(diào)用次數(shù),代表沒有重試,也就是沒有斷路器異常。 本系列代碼地址:??https://github.com/JoJoTec/spring-cloud-parent??我們來測(cè)試下前面封裝好的 We...

    番茄西紅柿 評(píng)論0 收藏2637
  • SpringCloud升級(jí)之路2020.0.x版-40. spock 單元測(cè)試封裝的 WebClie

    摘要:本系列代碼地址我們繼續(xù)上一節(jié),繼續(xù)使用測(cè)試我們自己封裝的測(cè)試針對(duì)重試測(cè)試針對(duì)重試針對(duì)響應(yīng)超時(shí),我們需要驗(yàn)證重試僅針對(duì)可以重試的方法包括方法以及配置的可重試方法,針對(duì)不可重試的方法沒有重試。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent我們繼續(xù)上一節(jié),繼續(xù)使用 spock 測(cè)試我們自己封裝的 WebClient測(cè)試針對(duì) readTi...

    番茄西紅柿 評(píng)論0 收藏2637
  • 使用 Resilience4j 框架實(shí)現(xiàn)重試機(jī)制

    摘要:重試會(huì)增加的響應(yīng)時(shí)間。提供了輔助方法來為包含遠(yuǎn)程調(diào)用的函數(shù)式接口或表達(dá)式創(chuàng)建裝飾器。如果我們想創(chuàng)建一個(gè)裝飾器并在代碼庫的不同位置重用它,我們將使用。 在本文中,我們將從快速介紹 Resilience4j 開始,然后深入探討其 Retry 模塊。我們將了解何時(shí)、如何使用它,以及它提供的功能。在此過程中,我們還將學(xué)...

    番茄西紅柿 評(píng)論0 收藏2637
  • SpringCloud升級(jí)之路2020.0.x版-36. 驗(yàn)證斷路器正確性

    摘要:本系列代碼地址上一節(jié)我們通過單元測(cè)試驗(yàn)證了線程隔離的正確性,這一節(jié)我們來驗(yàn)證我們斷路器的正確性,主要包括驗(yàn)證配置正確加載即我們?cè)谂渲美缰械募尤氲牡呐渲帽徽_加載應(yīng)用了。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent上一節(jié)我們通過單元測(cè)試驗(yàn)證了線程隔離的正確性,這一節(jié)我們來驗(yàn)證我們斷路器的正確性,主要包括:驗(yàn)證配置正確加載:即我們...

    NotFound 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<