Resilience4J 介紹


Netflix Hystrix 斷路器是 Spring Cloud 中最早就開始支持的一種服務調用容錯解決方案,但是目前的 Hystrix 已經處於維護模式了,雖然這並不影響已經上線的項目,並且在短期內,你甚至也可以繼續在項目中使用 Hystrix 。但是長遠來看,處於維護狀態的 Hystrix 走下歷史舞台只是一個時間問題,特別是在 Spring Cloud Greenwich 版中,官方已經給出了 Hystrix 的建議替代方案。如下圖:

Resilience4j 是 Spring Cloud Greenwich 版推薦的容錯解決方案,它是一個輕量級的容錯庫,受 Netflix Hystrix 的啟發而設計,它專為 Java 8 和函數式編程而設計。

Resilience4j 非常輕量級,因為它的庫只使用 Vavr (以前稱為 Javaslang ),它沒有任何其他外部庫依賴項。相比之下, Netflix Hystrix 對Archaius 具有編譯依賴性,這導致了更多的外部庫依賴,例如 Guava 和 Apache Commons 。而如果使用Resilience4j,你無需引用全部依賴,可以根據自己需要的功能引用相關的模塊即可。

Resilience4j 也提供了一系列增強微服務可用性的功能,主要功能如下:

  • 斷路器
  • 限流
  • 基於信號量的隔離
  • 緩存
  • 限時
  • 請求重試

接下來,我們就先來看通過一個普通的Maven項目來看 Resilience4j 中這幾個功能的基本用法。

上面提到的 Resilience4j 中的功能,每一個功能都對應了一個依賴。我們創建好Maven項目后,再添加單元測試依賴:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

一、Resilience4j 的功能介紹

斷路器有三種正常狀態:完全打開OPEN,半開HALF_OPEN,關閉CLOSED,還有兩種通過設置的強制狀態:強制不可用DISABLED,強制打開FORCED_OPEN。

斷路器初始化

使用 Resilience4j 提供的斷路器功能,需要我們首先加入如下依賴:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-circuitbreaker</artifactId>
    <version>1.5.0</version>
</dependency>

這個庫提供了一個基於 ConcurrentHashMap 的 CircuitBreakerRegistry ,CircuitBreakerRegistry 是線程安全的,並且是原子操作。開發者可以使用 CircuitBreakerRegistry 來創建和檢索 CircuitBreaker 的實例 ,開發者可以直接使用默認的全局CircuitBreakerConfig 為所有 CircuitBreaker 實例創建 CircuitBreakerRegistry ,如下所示:

CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults();

當然開發者也可以提供自己的 CircuitBreakerConfig ,然后根據自定義的 CircuitBreakerConfig 來創建一個 CircuitBreakerRegistry 實例,進而創建 CircuitBreaker 實例。如果我們使用自定義的 CircuitBreakerConfig :

CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
        .failureRateThreshold(50) //默認為50,即失敗率閾值為50%, 超過這個閾值,斷路器就會打開
        .waitDurationInOpenState(Duration.ofMillis(1000)) // 用來指定斷路器從OPEN到HALF_OPEN狀態等待的時長,默認是60秒
        .permittedNumberOfCallsInHalfOpenState(2) //熔斷器半開時的限制線程的並發量
        .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) // 滑動窗口類型,有基於時間TIME_BASED和基於計數COUNT_BASED
        .slidingWindowSize(2) //滑動窗口大小,默認是基於計數的滑動窗口類型
        .automaticTransitionFromOpenToHalfOpenEnabled(false) //當waitDurationInOpenState時間一過,是否自動從OPEN切換到HALF_OPEN,默認為false
        .build();
// 配置CircuitBreakerRegistry
CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);
// 創建兩個斷路器
CircuitBreaker circuitBreaker2 = circuitBreakerRegistry.circuitBreaker("otherName");
CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("uniqueName", circuitBreakerConfig);

如果開發者不想使用 CircuitBreakerRegistry 來管理斷路器,那么也可以直接創建一個 CircuitBreaker 對象,創建方式如下:

 CircuitBreaker defaultCircuitBreaker = CircuitBreaker.ofDefaults("testName");
 CircuitBreaker customCircuitBreaker = CircuitBreaker.of("testName", circuitBreakerConfig);
斷路器使用案例

斷路器使用了裝飾者模式,開發者可以使用 CircuitBreaker.decorateCheckedSupplier(), CircuitBreaker.decorateCheckedRunnable() 或者 CircuitBreaker.decorateCheckedFunction() 來裝飾 Supplier / Runnable / Function 或者 CheckedRunnable / CheckedFunction,然后使用 Try.of(…​) 或者 Try.run(…​) 來進行調用操作,也可以使用 map、flatMap、filter、recover 或者 andThen 進行鏈式調用,但是調用這些方法斷路器必須處於 CLOSED 或者 HALF_OPEN 狀態。例如下面一個例子,創建一個斷路器出來,首先裝飾了一個函數,這個函數返回一段字符串,然后使用 Try.of 去執行,執行完后再進入到 map 中去執行。如果第一個函數正常執行第二個函數才會執行,如果第一個函數執行失敗,那么 map 函數將不會執行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM