一個輕量級的容錯庫—Resilience4j,Hystrix的替代品,斷路器、限流、隔離艙、重試、快取全部搞定。
Netflix宣佈停止開發Hystrix,建議使用Resilience4j,Resilience4j到底是什麼鬼?Resilience4j最新版本為0.13.2,無論是案例還是活躍度,都不及Hystrix,帶著這些疑問,讓我們來了解一下Resilience4j。
首先,我先簡單對比一下二者。
-
實際上Resilience4j的靈感來自於Hystrix,同樣是輕量級的分散式容錯方法庫,比Hystrix的功能更豐富一些;
-
Hystrix是基於Command模式的,而Resilience4j利用了Java 8 的函數語言程式設計思想;
-
Hystrix需要依賴於Archaius,Archaius又依賴於第三方庫Guava和Apache Commons Configuration,而Resilience4j只依賴Vavr庫(前身是Javaslang)。
Resilience4j的核心模組包括斷路器、限流、隔離艙、重試、快取等,他們都是獨立編譯的,如果你僅僅需要其中的一部分,則可以部分引入。
-
resilience4j-circuitbreaker: Circuit breaking
-
resilience4j-ratelimiter: Rate limiting
-
resilience4j-bulkhead: Bulkheading
-
resilience4j-retry: Automatic retrying (sync and async)
-
resilience4j-cache: Response caching
-
resilience4j-timelimiter: Timeout handling
話不多說,直接上程式碼,如何實現一個斷路器? 首先引入包,
<dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-circuitbreaker</artifactId> <version>0.13.1</version> </dependency>`
建立一個自定義配置的斷路器,
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(80) //失敗率閾值百分比,以百分比形式配置故障率閾值,高於該百分比,CircuitBreaker應跳閘並開始呼叫短路。閾值必須大於0且不大於100.預設值為50%。
.waitDurationInOpenState(Duration.ofMillis(1000))//等待持續時間,該持續時間指定CircuitBreaker在切換到半開之前應保持開啟的時間。預設60秒。
.ringBufferSizeInHalfOpenState(20)//預設為100,狀態為半開啟時,環形緩衝區的大小,這裡需要注意,如果設定為20,則必須要評估20次呼叫,才能計算出失敗率,少於19次,無論失敗率是多少都沒用。
.ringBufferSizeInClosedState(20)
.build();
//通過全域性配置建立斷路器
CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);
CircuitBreaker circuitBreaker2 = circuitBreakerRegistry.circuitBreaker("otherName");
//當然,你也可以不使用全域性配置建立斷路器
CircuitBreaker defaultCircuitBreaker = CircuitBreaker.ofDefaults("testName");
這裡需要注意的是如果name相同,則認為是同一個斷路器。
@Test
public void shouldBeTheSameCircuitBreaker() {
CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("testName");
CircuitBreaker circuitBreaker2 = circuitBreakerRegistry.circuitBreaker("testName");
assertThat(circuitBreaker).isSameAs(circuitBreaker2);
assertThat(circuitBreakerRegistry.getAllCircuitBreakers()).hasSize(1);
}
另外,你也可以通過Predicate過濾異常,也就是說,可以設定哪些異常可以觸發斷路器,哪些不觸發。
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
// 返回失敗百分比
float failureRate = metrics.getFailureRate();
// 返回當前緩衝的呼叫數
int bufferedCalls = metrics.getNumberOfBufferedCalls();
// 返回當前失敗的呼叫數
int failedCalls = metrics.getNumberOfFailedCalls();
當然,你可以可以基於AOP實現斷路器,
@CircuitBreaker(name = "backendA", recovery = MyRecoveryFunction.class)
@Singleton
public class BackendAConnector implements Connector {
...
}
也可以提供了介面獲取一些監控指標。可以和Prometheus整合。
斷路器採用Ring Bit Buffer儲存開啟、關閉等狀態,使用了一個16位的long陣列,每個long 64 bit,這樣可以儲存1024次呼叫的狀態,非常節約儲存,值得借鑑。
其他模組用法類似,可以參考官網。
總結:大概瀏覽了一下原始碼,程式碼質量不錯,邏輯清晰,可讀性非常高。幾乎可以不用看註釋、文件,可以預見,resilience4j一定是一個未來被很多框架引用的基礎庫。
參考:https://github.com/resilience4j/resilience4j