Java 專案中使用 Resilience4j 框架實現隔斷機制/斷路器

信碼由韁發表於2021-12-04


到目前為止,在本系列中,我們已經瞭解了 Resilience4j 及其 Retry, RateLimiter, TimeLimiter, 和 Bulkhead 模組。在本文中,我們將探索 CircuitBreaker 模組。我們將瞭解何時以及如何使用它,並檢視一些示例。

程式碼示例

本文附有 GitHub 上的工作程式碼示例。

什麼是 Resilience4j?

請參閱上一篇文章中的描述,快速瞭解 Resilience4j 的一般工作原理

什麼是斷路器?

斷路器的思想是,如果我們知道呼叫可能會失敗或超時,則阻止對遠端服務的呼叫。我們這樣做是為了不會在我們的服務和遠端服務中不必要地浪費關鍵資源。這樣的退出也給了遠端服務一些時間來恢復。

我們怎麼知道一個呼叫可能會失敗? 通過跟蹤對遠端服務發出的先前請求的結果。例如,如果前 10 次呼叫中有 8 次導致失敗或超時,則下一次呼叫也可能會失敗。

斷路器通過包裝對遠端服務的呼叫來跟蹤響應。在正常執行期間,當遠端服務成功響應時,我們說斷路器處於“閉合”狀態。當處於關閉狀態時,斷路器正常將請求傳遞給遠端服務。

當遠端服務返回錯誤或超時時,斷路器會增加一個內部計數器。如果錯誤計數超過配置的閾值,斷路器將切換到“斷開”狀態。當處於斷開狀態時,斷路器立即向呼叫者返回錯誤,甚至無需嘗試遠端呼叫。

經過一段配置的時間後,斷路器從斷開狀態切換到“半開”狀態。在這種狀態下,它允許一些請求傳遞到遠端服務以檢查它是否仍然不可用或緩慢。 如果錯誤率或慢呼叫率高於配置的閾值,則切換回斷開狀態。但是,如果錯誤率或慢呼叫率低於配置的閾值,則切換到關閉狀態以恢復正常操作。

斷路器的型別

斷路器可以基於計數或基於時間。如果最後 N 次呼叫失敗或緩慢,則基於計數的斷路器將狀態從關閉切換為斷開。如果最後 N 秒的響應失敗或緩慢,則基於時間的斷路器將切換到斷開狀態。在這兩個斷路器中,我們還可以指定失敗或慢速呼叫的閾值。

例如,如果最近 25 次呼叫中有 70% 失敗或需要 2 秒以上才能完成,我們可以配置一個基於計數的斷路器來“斷開電路”。同樣,如果過去 30 秒內 80% 的呼叫失敗或耗時超過 5 秒,我們可以告訴基於時間的斷路器斷開電路。

Resilience4j 的 CircuitBreaker 概念

resilience4j-circuitbreaker 的工作原理與其他 Resilience4j 模組類似。我們提供想要作為函式構造執行的程式碼——一個進行遠端呼叫的 lambda 表示式或一個從遠端服務中檢索到的某個值的 Supplier,等等——並且斷路器用程式碼修飾它 如果需要,跟蹤響應並切換狀態。

Resilience4j 同時支援基於計數和基於時間的斷路器。

我們使用 slidingWindowType() 配置指定斷路器的型別。此配置可以採用兩個值之一 -
SlidingWindowType.COUNT_BASED
SlidingWindowType.TIME_BASED

failureRateThreshold()slowCallRateThreshold() 以百分比形式配置失敗率閾值和慢速呼叫率。

slowCallDurationThreshold() 以秒為單位配置呼叫被認為慢的時間。

我們可以指定一個 minimumNumberOfCalls(),在斷路器可以計算錯誤率或慢速呼叫率之前需要它。

如前所述,斷路器在一定時間後從斷開狀態切換到半斷開狀態,以檢查遠端服務的情況。waitDurationInOpenState() 指定斷路器在切換到半開狀態之前應等待的時間。

permittedNumberOfCallsInHalfOpenState() 配置在半開狀態下允許的呼叫次數,
maxWaitDurationInHalfOpenState() 確定斷路器在切換回開狀態之前可以保持在半開狀態的時間。

此配置的預設值 0 意味著斷路器將無限等待,直到所有
permittedNumberOfCallsInHalfOpenState() 完成。

預設情況下,斷路器將任何異常視為失敗。但是我們可以對此進行調整,以使用 recordExceptions() 配置指定應視為失敗的異常列表和使用 ignoreExceptions() 配置忽略的異常列表。

如果我們在確定異常應該被視為失敗還是忽略時想要更精細的控制,我們可以提供 Predicate<Throwable> 作為 recordException()ignoreException() 配置。

當斷路器拒絕處於斷開狀態的呼叫時,它會丟擲 CallNotPermittedException。我們可以使用 writablestacktraceEnabled() 配置控制 CallNotPermittedException 的堆疊跟蹤中的資訊量。

使用 Resilience4j CircuitBreaker模組

讓我們看看如何使用
resilience4j-circuitbreaker 模組中可用的各種功能。

我們將使用與本系列前幾篇文章相同的示例。假設我們正在為一家航空公司建立一個網站,以允許其客戶搜尋和預訂航班。我們的服務與 FlightSearchService 類封裝的遠端服務對話。

使用 Resilience4j 斷路器時,CircuitBreakerRegistryCircuitBreakerConfigCircuitBreaker 是我們使用的主要抽象。

CircuitBreakerRegistry 是用於建立和管理 CircuitBreaker 物件的工廠。

CircuitBreakerConfig 封裝了上一節中的所有配置。每個 CircuitBreaker 物件都與一個 CircuitBreakerConfig 相關聯。

第一步是建立一個 CircuitBreakerConfig

CircuitBreakerConfig config = CircuitBreakerConfig.ofDefaults();

這將建立一個具有以下預設值的 CircuitBreakerConfig:

配置預設值
slidingWindowTypeCOUNT_BASED
failureRateThreshold50%
slowCallRateThreshold100%
slowCallDurationThreshold60s
minimumNumberOfCalls100
permittedNumberOfCallsInHalfOpenState10
maxWaitDurationInHalfOpenState0s

基於計數的斷路器

假設我們希望斷路器在最近 10 次呼叫中有 70% 失敗時斷開:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.COUNT_BASED)
  .slidingWindowSize(10)
  .failureRateThreshold(70.0f)
  .build();

然後我們用這個配置建立一個 CircuitBreaker

CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("flightSearchService");

現在讓我們表達我們的程式碼以作為 Supplier 執行航班搜尋並使用 circuitbreaker 裝飾它:

Supplier<List<Flight>> flightsSupplier =
  () -> service.searchFlights(request);
Supplier<List<Flight>> decoratedFlightsSupplier =
  circuitBreaker.decorateSupplier(flightsSupplier);

最後,讓我們呼叫幾次修飾操作來了解斷路器的工作原理。我們可以使用 CompletableFuture 來模擬來自使用者的併發航班搜尋請求:

for (int i=0; i<20; i++) {
  try {
    System.out.println(decoratedFlightsSupplier.get());
  }
  catch (...) {
    // Exception handling
  }
}

輸出顯示前幾次飛行搜尋成功,然後是 7 次飛行搜尋失敗。此時,斷路器斷開併為後續呼叫丟擲 CallNotPermittedException

Searching for flights; current time = 12:01:12 884
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 12:01:12 954
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 12:01:12 957
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 12:01:12 958
io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Error occurred during flight search
... stack trace omitted ...
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
... other lines omitted ...
io.reflectoring.resilience4j.circuitbreaker.Examples.countBasedSlidingWindow_FailedCalls(Examples.java:56)
  at io.reflectoring.resilience4j.circuitbreaker.Examples.main(Examples.java:229)

現在,假設我們希望斷路器在最後 10 個呼叫中有 70% 需要 2 秒或更長時間才能完成:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.COUNT_BASED)
  .slidingWindowSize(10)
  .slowCallRateThreshold(70.0f)
  .slowCallDurationThreshold(Duration.ofSeconds(2))
  .build();

示例輸出中的時間戳顯示請求始終需要 2 秒才能完成。在 7 次緩慢響應後,斷路器斷開並且不允許進一步呼叫:

Searching for flights; current time = 12:26:27 901
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 12:26:29 953
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 12:26:31 957
Flight search successful
... other lines omitted ...
Searching for flights; current time = 12:26:43 966
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
... stack trace omitted ...
        at io.reflectoring.resilience4j.circuitbreaker.Examples.main(Examples.java:231)
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
... stack trace omitted ...
        at io.reflectoring.resilience4j.circuitbreaker.Examples.main(Examples.java:231)

通常我們會配置一個具有故障率和慢速呼叫率閾值的斷路器:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.COUNT_BASED)
  .slidingWindowSize(10)
  .failureRateThreshold(70.0f)
  .slowCallRateThreshold(70.0f)
  .slowCallDurationThreshold(Duration.ofSeconds(2))
  .build();

基於時間的斷路器

假設我們希望斷路器在過去 10 秒內 70% 的請求失敗時斷開:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.COUNT_BASED)
  .slidingWindowSize(10)
  .failureRateThreshold(70.0f)
  .slowCallRateThreshold(70.0f)
  .slowCallDurationThreshold(Duration.ofSeconds(2))
  .build();

我們建立了 CircuitBreaker,將航班搜尋呼叫表示為 Supplier<List<Flight>> 並使用 CircuitBreaker 對其進行裝飾,就像我們在上一節中所做的那樣。

以下是多次呼叫修飾操作後的示例輸出:

Start time: 18:51:01 552
Searching for flights; current time = 18:51:01 582
Flight search successful
[Flight{flightNumber='XY 765', ... }]
... other lines omitted ...
Searching for flights; current time = 18:51:01 631
io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Error occurred during flight search
... stack trace omitted ...
Searching for flights; current time = 18:51:01 632
io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Error occurred during flight search
... stack trace omitted ...
Searching for flights; current time = 18:51:01 633
... other lines omitted ...
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
... other lines omitted ...

前 3 個請求成功,接下來的 7 個請求失敗。此時斷路器斷開,後續請求因丟擲 CallNotPermittedException 而失敗。

現在,假設我們希望斷路器在過去 10 秒內 70% 的呼叫需要 1 秒或更長時間才能完成:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.TIME_BASED)
  .minimumNumberOfCalls(10)
  .slidingWindowSize(10)
  .slowCallRateThreshold(70.0f)
  .slowCallDurationThreshold(Duration.ofSeconds(1))
  .build();

示例輸出中的時間戳顯示請求始終需要 1 秒才能完成。在 10 個請求(minimumNumberOfCalls)之後,當斷路器確定 70% 的先前請求花費了 1 秒或更長時間時,它斷開電路:

Start time: 19:06:37 957
Searching for flights; current time = 19:06:37 979
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 19:06:39 066
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 19:06:40 070
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 19:06:41 070
... other lines omitted ...
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
... stack trace omitted ...

通常我們會配置一個具有故障率和慢速呼叫率閾值的基於時間的斷路器:

指定斷開狀態下的等待時間

假設我們希望斷路器處於斷開狀態時等待 10 秒,然後轉換到半斷開狀態並讓一些請求傳遞到遠端服務:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.TIME_BASED)
  .slidingWindowSize(10)
  .minimumNumberOfCalls(10)
  .failureRateThreshold(70.0f)
  .slowCallRateThreshold(70.0f)
  .slowCallDurationThreshold(Duration.ofSeconds(2))
  .build();

示例輸出中的時間戳顯示斷路器最初轉換為斷開狀態,在接下來的 10 秒內阻止一些呼叫,然後更改為半斷開狀態。後來,在半開狀態時一致的成功響應導致它再次切換到關閉狀態:

Searching for flights; current time = 20:55:58 735
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 20:55:59 812
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 20:56:00 816
... other lines omitted ...
io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Flight search failed
    at
... stack trace omitted ...
2020-12-13T20:56:03.850115+05:30: CircuitBreaker 'flightSearchService' changed state from CLOSED to OPEN
2020-12-13T20:56:04.851700+05:30: CircuitBreaker 'flightSearchService' recorded a call which was not permitted.
2020-12-13T20:56:05.852220+05:30: CircuitBreaker 'flightSearchService' recorded a call which was not permitted.
2020-12-13T20:56:06.855338+05:30: CircuitBreaker 'flightSearchService' recorded a call which was not permitted.
... other similar lines omitted ...
2020-12-13T20:56:12.862362+05:30: CircuitBreaker 'flightSearchService' recorded a call which was not permitted.
2020-12-13T20:56:13.865436+05:30: CircuitBreaker 'flightSearchService' changed state from OPEN to HALF_OPEN
Searching for flights; current time = 20:56:13 865
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
... other similar lines omitted ...
2020-12-13T20:56:16.877230+05:30: CircuitBreaker 'flightSearchService' changed state from HALF_OPEN to CLOSED
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 20:56:17 879
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
... other similar lines omitted ...

指定回退方法

使用斷路器時的常見模式是指定在電路斷開時要呼叫的回退方法。回退方法可以為不允許的遠端呼叫提供一些預設值或行為

我們可以使用 Decorators 實用程式類進行設定。Decorators 是來自 resilience4j-all 模組的構建器,具有 withCircuitBreaker()withRetry()withRateLimiter() 等方法,可幫助將多個 Resilience4j 裝飾器應用於 SupplierFunction 等。

當斷路器斷開並丟擲 CallNotPermittedException 時,我們將使用它的 withFallback() 方法從本地快取返回航班搜尋結果:

Supplier<List<Flight>> flightsSupplier = () -> service.searchFlights(request);
Supplier<List<Flight>> decorated = Decorators
  .ofSupplier(flightsSupplier)
  .withCircuitBreaker(circuitBreaker)
  .withFallback(Arrays.asList(CallNotPermittedException.class),
                e -> this.getFlightSearchResultsFromCache(request))
  .decorate();

以下示例輸出顯示了斷路器斷開後從快取中返回的搜尋結果:

Searching for flights; current time = 22:08:29 735
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 22:08:29 854
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 22:08:29 855
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Searching for flights; current time = 22:08:29 855
2020-12-13T22:08:29.856277+05:30: CircuitBreaker 'flightSearchService' recorded an error: 'io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Error occurred during flight search'. Elapsed time: 0 ms
Searching for flights; current time = 22:08:29 912
... other lines omitted ...
2020-12-13T22:08:29.926691+05:30: CircuitBreaker 'flightSearchService' changed state from CLOSED to OPEN
Returning flight search results from cache
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
Returning flight search results from cache
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... }]
... other lines omitted ...

減少 Stacktrace 中的資訊

每當斷路器斷開時,它就會丟擲 CallNotPermittedException

io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
    at io.github.resilience4j.circuitbreaker.CallNotPermittedException.createCallNotPermittedException(CallNotPermittedException.java:48)
... other lines in stack trace omitted ...
at io.reflectoring.resilience4j.circuitbreaker.Examples.timeBasedSlidingWindow_SlowCalls(Examples.java:169)
    at io.reflectoring.resilience4j.circuitbreaker.Examples.main(Examples.java:263)

除了第一行,堆疊跟蹤中的其他行沒有增加太多價值。如果 CallNotPermittedException 發生多次,這些堆疊跟蹤行將在我們的日誌檔案中重複。

我們可以通過將 writablestacktraceEnabled() 配置設定為 false 來減少堆疊跟蹤中生成的資訊量:

CircuitBreakerConfig config = CircuitBreakerConfig
  .custom()
  .slidingWindowType(SlidingWindowType.COUNT_BASED)
  .slidingWindowSize(10)
  .failureRateThreshold(70.0f)
  .writablestacktraceEnabled(false)
  .build();

現在,當 CallNotPermittedException 發生時,堆疊跟蹤中只存在一行:

Searching for flights; current time = 20:29:24 476
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
Searching for flights; current time = 20:29:24 540
Flight search successful
[Flight{flightNumber='XY 765', flightDate='12/31/2020', from='NYC', to='LAX'}, ... ]
... other lines omitted ...
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'flightSearchService' is OPEN and does not permit further calls
...

其他有用的方法

Retry 模組類似,CircuitBreaker 也有像 ignoreExceptions()recordExceptions() 等方法,讓我們可以指定 CircuitBreaker 在跟蹤呼叫結果時應該忽略和考慮哪些異常。

例如,我們可能不想忽略來自遠端飛行服務的 SeatsUnavailableException - 在這種情況下,我們真的不想斷開電路。

與我們見過的其他 Resilience4j 模組類似,CircuitBreaker 還提供了額外的方法,如 decorateCheckedSupplier()decorateCompletionStage()decorateRunnable()decorateConsumer() 等,因此我們可以在 Supplier 之外的其他結構中提供我們的程式碼。

斷路器事件

CircuitBreaker 有一個 EventPublisher 可以生成以下型別的事件:

  • CircuitBreakerOnSuccessEvent,
  • CircuitBreakerOnErrorEvent,
  • CircuitBreakerOnStateTransitionEvent,
  • CircuitBreakerOnResetEvent,
  • CircuitBreakerOnIgnoredErrorEvent,
  • CircuitBreakerOnCallNotPermittedEvent,
  • CircuitBreakerOnFailureRateExceededEvent 以及
  • CircuitBreakerOnSlowCallRateExceededEvent.

我們可以監聽這些事件並記錄它們,例如:

circuitBreaker.getEventPublisher()
  .onCallNotPermitted(e -> System.out.println(e.toString()));
circuitBreaker.getEventPublisher()
  .onError(e -> System.out.println(e.toString()));
circuitBreaker.getEventPublisher()
  .onFailureRateExceeded(e -> System.out.println(e.toString()));
circuitBreaker.getEventPublisher().onStateTransition(e -> System.out.println(e.toString()));

以下是示例的日誌輸出:

2020-12-13T22:25:52.972943+05:30: CircuitBreaker 'flightSearchService' recorded an error: 'io.reflectoring.resilience4j.circuitbreaker.exceptions.FlightServiceException: Error occurred during flight search'. Elapsed time: 0 ms
Searching for flights; current time = 22:25:52 973
... other lines omitted ...
2020-12-13T22:25:52.974448+05:30: CircuitBreaker 'flightSearchService' exceeded failure rate threshold. Current failure rate: 70.0
2020-12-13T22:25:52.984300+05:30: CircuitBreaker 'flightSearchService' changed state from CLOSED to OPEN
2020-12-13T22:25:52.985057+05:30: CircuitBreaker 'flightSearchService' recorded a call which was not permitted.
... other lines omitted ...

CircuitBreaker指標

CircuitBreake 暴露了許多指標,這些是一些重要的條目:

  • 成功、失敗或忽略的呼叫總數 (resilience4j.circuitbreaker.calls)
  • 斷路器狀態 (resilience4j.circuitbreaker.state)
  • 斷路器故障率 (resilience4j.circuitbreaker.failure.rate)
  • 未被允許的呼叫總數 (resilience4.circuitbreaker.not.permitted.calls)
  • 斷路器的緩慢呼叫 (resilience4j.circuitbreaker.slow.call.rate)

首先,我們像往常一樣建立 CircuitBreakerConfigCircuitBreakerRegistryCircuitBreaker。然後,我們建立一個 MeterRegistry 並將 CircuitBreakerRegistry 繫結到它:

MeterRegistry meterRegistry = new SimpleMeterRegistry();
TaggedCircuitBreakerMetrics.ofCircuitBreakerRegistry(registry)
  .bindTo(meterRegistry);

執行幾次斷路器修飾操作後,我們顯示捕獲的指標。這是一些示例輸出:

The number of slow failed calls which were slower than a certain threshold - resilience4j.circuitbreaker.slow.calls: 0.0
The states of the circuit breaker - resilience4j.circuitbreaker.state: 0.0, state: metrics_only
Total number of not permitted calls - resilience4j.circuitbreakernot.permitted.calls: 0.0
The slow call of the circuit breaker - resilience4j.circuitbreaker.slow.call.rate: -1.0
The states of the circuit breaker - resilience4j.circuitbreaker.state: 0.0, state: half_open
Total number of successful calls - resilience4j.circuitbreaker.calls: 0.0, kind: successful
The failure rate of the circuit breaker - resilience4j.circuitbreaker.failure.rate: -1.0

在實際應用中,我們會定期將資料匯出到監控系統並在儀表板上進行分析。

結論

在本文中,我們學習瞭如何使用 Resilience4j 的 Circuitbreaker 模組在遠端服務返回錯誤時暫停向其發出請求。我們瞭解了為什麼這很重要,還看到了一些有關如何配置它的實際示例。

您可以使用 GitHub 上的程式碼來演示一個完整的應用程式。


本文譯自:Implementing a Circuit Breaker with Resilience4j - Reflectoring

相關文章