正如 Resilience4J 的创建者Robert Winkler回答的那样,使用装饰器在供应商上组合/应用 3 种弹性模式。根据执行和弹性的需要调整它们的顺序。
装饰器的顺序对执行有影响
Decorators
builder的 JavaDoc解释了build-chain order的效果:
装饰器按构建器链的顺序应用。
例如,考虑:
Supplier<String> supplier = Decorators
.ofSupplier(() -> service.method()) // 1. called and result handled in order:
.withCircuitBreaker(CircuitBreaker.ofDefaults("id")) // 2. circuit-breaker
.withRetry(Retry.ofDefaults("id")) // 3. retry
.withFallback(CallNotPermittedException.class,
e -> service.fallbackMethod()) // 4. fallback
.decorate();
(我添加了注释以强调执行顺序)
这会在执行供应商时产生以下组合:
Fallback(Retry(CircuitBreaker(Supplier)))
这意味着首先调用Supplier,然后其结果由CircuitBreaker处理,然后是Retry,然后是Fallback。
集成客户端RateLimiter
正如 Reflectoring 的教程Implementing Rate Limiting with Resilience4j - Reflectoring中所推荐的:
一起使用 RateLimiter 和重试
[..] 我们会像往常一样创建对象RateLimiter
。Retry
然后我们装饰一个速率限制 Supplier
并用: [example]包装它Retry
订购建议
将此“Retry with RateLimiter”与上述 JavaDoc 示例和 Robert 的回答进行比较,我建议选择以下执行顺序:
- 供应商,然后用弹性按顺序装饰:
RateLimiter
(如果超出速率限制,则阻止呼叫)
TimeLimiter
(暂停通话)
CircuitBreaker
(快速失败)
Retry
(重试异常)
Fallback
(后备作为最后的手段)
例如,在 Spring-Boot 扩展中自动配置了合适的参考顺序。请参阅官方指南, Aspect order入门resilience4j-spring-boot2
:
Resilience4j Aspects 顺序如下:
Retry ( CircuitBreaker ( RateLimiter ( TimeLimiter ( Bulkhead ( Function ) ) ) ) )
所以最后应用重试(如果需要)。
也可以看看: