Reactive Feign Client原有全局重试失效,如何配置全局重试规则?
核心结论
你原来的同步Retryer完全无法适配Reactive Feign场景,二者底层IO模型不兼容,无需尝试适配原有实现,直接基于Reactor重试算子配置全局重试即可,不需要为每个调用单独配置。
不生效的根本原因
原生Feign提供的Retryer是为同步阻塞客户端设计的,内部依赖Thread.sleep()实现重试间隔等待,逻辑完全绑定同步IO模型。而Reactive Feign基于非阻塞反应式模型实现,不会调用这套同步重试逻辑,所以即使ErrorDecoder正常抛出RetryableException也不会触发重试。
全局重试配置方案
你可以通过ReactiveFeignCustomizer全局注入重试策略,所有Reactive Feign客户端都会自动生效,不需要修改原有业务调用代码,原有ErrorDecoder的逻辑也可以完全复用。
示例配置代码如下:
import reactor.util.retry.Retry; import java.time.Duration; import feign.codec.ErrorDecoder; import feign.RetryableException; import org.springframework.cloud.openfeign.ReactiveFeignCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.core.Exceptions; import lombok.extern.slf4j.Slf4j; @Slf4j @Configuration public class GlobalReactiveFeignConfig { @Bean public ReactiveFeignCustomizer globalRetryCustomizer() { // 完全对齐你原有重试配置:初始间隔100ms,最大重试5次 Retry retrySpec = Retry.fixedDelay(5, Duration.ofMillis(100)) // 只重试ErrorDecoder抛出的RetryableException,和原有逻辑一致 .filter(throwable -> Exceptions.unwrap(throwable) instanceof RetryableException) // 可按需添加重试日志 .doBeforeRetry(signal -> log.debug("Feign request retry attempt {}: {}", signal.totalRetries() + 1, signal.failure().getMessage())); return builder -> builder.addMethodHandler((method, next) -> proxy -> ((Mono<?>) next.invoke(proxy)).retryWhen(retrySpec) ); } // 原有ErrorDecoder逻辑完全保留即可,不需要修改 @Bean ErrorDecoder errorDecoder() { return new HttpErrorDecoder(); } static class HttpErrorDecoder implements ErrorDecoder { private final ErrorDecoder defaultErrorDecoder = new Default(); @Override public Exception decode(String methodKey, Response response) { Exception exception = defaultErrorDecoder.decode(methodKey, response); if (response.status() != HttpStatus.SC_OK) { return new RetryableException(response.status(), "api call for url: " + response.request().url() + " failed", response.request().httpMethod(), exception.getCause(), null, response.request()); } return exception; } } }
如果你使用的是非Spring官方的Reactive Feign实现(如Playtika reactive feign),核心逻辑一致,通过全局配置Builder为所有方法返回的Mono/Flux统一添加
retryWhen逻辑即可。
注意事项
- 仅对幂等请求(如GET、可重复执行的查询接口)开启重试,非幂等的提交类请求重试前需要自行判断业务风险,避免重复提交导致数据异常
- 如果需要为某个Feign客户端单独配置重试策略,只需要在对应
@FeignClient的自定义配置类中定义优先级更高的Retry规则即可,全局配置会被自动覆盖 - 如果需要更复杂的重试策略(如指数退避、按状态码重试等),直接修改
Retry的构造参数即可,Reactor提供了fixedDelay、backoff、maxInARow等多种开箱即用的重试配置
内容的提问来源于stack exchange,提问作者Patrik
相关产品推荐
相关产品推荐

