如何为Spring Boot的Reactive WebClient配置全局默认重试策略?
为Spring Boot的WebClient配置全局重试策略
完全可以通过ExchangeFilterFunction实现全局重试,不用修改每一处WebClient调用。核心思路是在创建WebClient实例时,添加全局过滤器拦截所有请求,统一注入重试逻辑。
步骤1:定义全局重试策略
先创建一个可复用的Retry Bean,根据业务需求配置重试规则:
@Bean public Retry globalWebClientRetry() { // 配置重试3次,每次间隔1秒,采用指数退避规则 return Retry.backoff(3, Duration.ofSeconds(1)) // 指定触发重试的异常类型:网络异常、服务端错误等 .filter(throwable -> throwable instanceof WebClientResponseException || throwable instanceof IOException) // 重试耗尽时抛出自定义异常 .onRetryExhaustedThrow((retrySpec, retrySignal) -> { throw new WebClientResponseException( "服务调用重试次数耗尽", HttpStatus.SERVICE_UNAVAILABLE.value(), HttpStatus.SERVICE_UNAVAILABLE.getReasonPhrase(), null, null, null ); }); }
步骤2:给WebClient添加全局重试过滤器
在创建WebClient的Bean时,通过两个过滤器实现全局重试:
@Bean public WebClient webClient(Retry globalWebClientRetry) { return WebClient.builder() // 过滤器1:将非2xx响应转为异常,让重试逻辑能捕获到 .filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { if (clientResponse.statusCode().isError()) { // 先消费响应体避免资源泄漏,再抛出异常 return clientResponse.bodyToMono(Void.class) .then(Mono.error(new WebClientResponseException( clientResponse.statusCode().getReasonPhrase(), clientResponse.statusCode().value(), clientResponse.statusCode().getReasonPhrase(), clientResponse.headers().asHttpHeaders(), null, null ))); } return Mono.just(clientResponse); })) // 过滤器2:给所有请求绑定全局重试策略 .filter((request, next) -> next.exchange(request) .retryWhen(globalWebClientRetry)) .build(); }
关键说明
- 全局生效:只要项目中所有WebClient调用都复用这个Bean,就会自动应用重试逻辑,无需修改调用代码
- 灵活覆盖:如果某几个请求不需要重试,可以在调用时临时覆盖:
webClient.get() .uri("/some-api") .retrieve() .bodyToMono(SomeDto.class) // 禁用当前请求的重试 .retryWhen(Retry.none()); - 幂等性注意:重试可能导致重复请求,建议只对GET、PUT等幂等请求启用全局重试;如果是POST这类非幂等请求,最好单独配置或禁用重试
内容的提问来源于stack exchange,提问作者Onki
相关产品推荐
相关产品推荐

