一个轻量级的容错库—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

猜你喜欢

转载自blog.csdn.net/douliw/article/details/85199079