Resilience4j Retry配置resultPredicate不生效问题排查
Resilience4j Retry组件未触发重试问题排查
问题描述
首次使用Resilience4j Retry组件,期望请求返回500状态码时重试3次,但sendUser方法未触发重试,自定义Predicate也未生效。
依赖配置
implementation group: 'org.springframework.boot', name: 'spring-boot-starter', version: '3.1.6' implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-circuitbreaker-resilience4j', version: '3.0.3' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '3.1.6'
业务代码实现
@Component public class MyService{ @Retry(name ="throwingFeignException") public String sendUser(Request request) { Response response = feignClient.send(eaziRequest); return response.getId(); } }
application.yaml配置
resilience4j: retry: instances: throwingFeignException: maxAttempts: 3 waitDuration: 60s retryExceptions: - feign.FeignException ignoreExceptions: - java.lang.Exception enableExponentialBackoff: true exponentialBackoffMultiplier: 5 resultPredicate: de.ruv.stammdaten.domain.eazi.backend.exception.ServerInternalErrorVerifier
自定义Predicate实现
@Slf4j public class ServerInternalErrorVerifier implements Predicate<FeignException> { @Override public boolean test(FeignException exception) { if(isServerError(exception)){ log.error("Server '{}' could not be achieved due of '{}'", exception.request().url(), exception.getMessage()); return true; } return false; } private static boolean isServerError(FeignException exception) { return exception.status() >= HttpStatus.INTERNAL_SERVER_ERROR.value(); } }
问题排查点及修复方案
1. 核心配置冲突:ignoreExceptions覆盖retryExceptions
配置中ignoreExceptions包含java.lang.Exception,而FeignException是Exception的子类,这会导致所有FeignException都被标记为「无需重试」,直接抵消retryExceptions的配置。
修复:删除ignoreExceptions: - java.lang.Exception,或仅添加需要忽略的具体异常类,避免使用顶层Exception。
2. resultPredicate使用场景错误
resultPredicate用于判断方法正常返回的结果是否需要重试,而你需要处理的是Feign调用抛出的FeignException(异常场景),应使用exceptionPredicate指定异常判断逻辑。
修复:将配置中的resultPredicate替换为exceptionPredicate:
exceptionPredicate: de.ruv.stammdaten.domain.eazi.backend.exception.ServerInternalErrorVerifier
3. 自定义Predicate实例化问题
确保ServerInternalErrorVerifier能被正常实例化:
- 若依赖Spring管理,给类添加
@Component注解; - 若不依赖Spring,确保类有无参构造函数(当前代码已满足)。
4. AOP代理生效检查
Resilience4j注解依赖Spring AOP代理,需满足:
MyService是通过Spring容器获取的Bean;- 调用
sendUser的代码不是MyService内部方法直接调用(内部调用不会触发AOP拦截),需通过Spring上下文获取自身Bean调用,或重构代码拆分调用逻辑。
5. 重试次数配置说明
maxAttempts: 3表示「1次初始调用 + 2次重试」,符合你的需求,该配置本身无问题。
内容的提问来源于stack exchange,提问作者Roma Kap
相关产品推荐
相关产品推荐

