Loading... ## 一、简介 Resilience4j 是一个轻量级的容错组件,其灵感来自于 Hystrix,但主要为 **Java 8** 和**函数式编程**所设计。 它更适用于**通过注解形式**的熔断限流处理。 <!--more--> 轻量级体现在其只用 Vavr 库,没有任何外部依赖。而 Hystrix 依赖了 Archaius,Archaius 本身又依赖很多第三方包,例如 Guava、Apache Commons Configuration 等等。 要使用 Resilience4j,不需要引入所有依赖,只需要引入你所需的模块。一般情况下,只需要引入 `resilience4j-spring-boot2`就够了。 ## 二、熔断器差异 Resilience4j 的熔断状态与 Hystrix 相同,但他们**记录请求状态的数据结构**有所不同: Hystrix 是使用滑动窗口来进行存储的,而 Resilience4j 采用的是 **`Ring Bit Buffer`(环形缓冲区)**。Ring Bit Buffer 在内部使用 `BitSet` 这样的数据结构来进行存储,结构如下图所示:  每一次请求的成功或失败状态只占用**一个 bit 位**,与 boolean 数组相比更节省内存。BitSet 使用 long[] 数组来存储这些数据,意味着 `16` 个值(64 bit)的数组可以存储 `1024` 个调用状态。 计算失败率需要填满环形缓冲区。这点跟Sentinel的最小阈值一样。 ## 三、注解比较 **`@Retry` > `@CircuitBreaker ` > `@RateLimiter` > `@TimeLimiter` > `@Bulkhead`**  * **`@Retry`** 在执行失败时,进行重试的行为。多次重试失败到达上限时,Resilience4j 会抛出 `MaxRetriesExceeded` 异常,然后就进入 fallback 降级处理。 * **`@CircuitBreaker`** 通过不同的 Throwable 异常,我们可以进行不同的 fallback 降级处理。极端情况下,Resilience4j 熔断器打开时,不会执行该方法,而是直接抛出 `CallNotPermittedException` 异常,然后也是进入 fallback 降级处理。 * **`@RateLimiter`** 默认情况下,采用 AtomicRateLimiter 基于令牌桶限流算法实现限流。在请求被限流时,Resilience4j 不会执行该方法,而是直接抛出 `RequestNotPermitted` 异常,然后就进入 fallback 降级处理。<br>注意,@RateLimiter 注解的 fallbackMethod 属性对应的 fallback 方法,不仅仅处理被限流时抛出的 RequestNotPermitted 异常,也处理该方法执行时的**普通异常**。 * **`@TimeLimiter`** 限制任务的执行时长,在超过时抛出 `TimeoutException` 异常,然后就进入 fallback 降级处理。需要搭配线程池类型的 Bulkhead。 * **`@Bulkhead`** 在请求被流控时,并不是直接失败抛出 `BulkheadFullException`异常,而是阻塞等待最大 `max-wait-duration` 微秒,看看是否能够请求通过。它也处理该方法执行时的**普通异常**。 ## 四、相关配置 ```xml resilience4j: # Resilience4j 的重试 Retry 配置项,对应 RetryProperties 属性类 retry: instances: backendE: max-retry-Attempts: 3 # 最大重试次数。默认为 3 wait-duration: 5s # 下次重试的间隔,单位:微秒。默认为 500 毫秒 retry-exceptions: # 需要重试的异常列表。默认为空 ingore-exceptions: # 需要忽略的异常列表。默认为空 # Resilience4j 的熔断器配置项,对应 CircuitBreakerProperties 属性类 circuitbreaker: instances: backendA: failure-rate-threshold: 50 # 熔断器关闭状态和半开状态使用的同一个失败率阈值,单位:百分比。默认为 50 ring-buffer-size-in-closed-state: 5 # 熔断器关闭状态的缓冲区大小,不会限制线程的并发量,在熔断器发生状态转换前所有请求都会调用后端服务。默认为 100 ring-buffer-size-in-half-open-state: 5 # 熔断器半开状态的缓冲区大小,会限制线程的并发量。例如,缓冲区为 10 则每次只会允许 10 个请求调用后端服务。默认为 10 wait-duration-in-open-state : 5000 # 熔断器从打开状态转变为半开状态等待的时间,单位:微秒 automatic-transition-from-open-to-half-open-enabled: true # 如果置为 true,当等待时间结束会自动由打开变为半开;若置为 false,则需要一个请求进入来触发熔断器状态转换。默认为 true register-health-indicator: true # 是否注册到健康监测 # Resilience4j 的限流器配置项,对应 RateLimiterProperties 属性类 ratelimiter: instances: backendB: limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50 limit-refresh-period: 10s # 每个周期的时长,单位:微秒。默认为 500 timeout-duration: 5s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s register-health-indicator: true # 是否注册到健康监测 # Resilience4j 的信号量 Bulkhead 配置项,对应 BulkheadConfigurationProperties 属性类 bulkhead: instances: backendC: max-concurrent-calls: 1 # 并发调用数。默认为 25 max-wait-duration: 5s # 并发调用到达上限时,阻塞等待的时长,单位:微秒。默认为 0 # Resilience4j 的超时限制器 TimeLimiter 配置项,对应 TimeLimiterProperties 属性类 timelimiter: instances: backendF: timeout-duration: 1s # 等待超时时间,单位:微秒。默认为 1 秒 cancel-running-future: true # 当等待超时时,是否关闭取消线程。默认为 true # Resilience4j 的线程池 Bulkhead 配置项,对应 ThreadPoolBulkheadProperties 属性类 thread-pool-bulkhead: instances: backendD: max-thread-pool-size: 1 # 线程池的最大大小。默认为 Runtime.getRuntime().availableProcessors() core-thread-pool-size: 1 # 线程池的核心大小。默认为 Runtime.getRuntime().availableProcessors() - 1 queue-capacity: 100 # 线程池的队列大小。默认为 100 keep-alive-duration: 100s # 超过核心大小的线程,空闲存活时间。默认为 20 毫秒 ``` ## 五、监控端点 Resilience4j 还扩展了许多与第三方监控系统对接的功能,如: * `Metrics endpoint`:纯 Endpoint 结尾。 `/actuator/metrics`路径下可以看到 Resilience4j 提供的所有 Metrics 监控指标。 * `Health endpoint`:HealthIndicator 结尾。 `/actuator/health`路径下可以看到 CircuitBreaker 和 RateLimiter 的健康状态。 * `Events endpoint`:EventsEndpoint 结尾。 `/actuator/类型events`路径下可以看到 Resilience4j当前类型的 Event 事件。 Last modification:August 22, 2022 © Allow specification reprint Like 0 喵ฅฅ