Resilience4j 1.7.1在JDK17环境下无法生效的问题排查求助
一、最初直接引入依赖启动失败的原因
你遇到的启动报错核心是Resilience4j 1.7.1与Spring Boot 2.6.2的依赖版本不兼容,具体是vavr类库的版本冲突。Resilience4j 1.7.x依赖的vavr版本和Spring Boot 2.6.x自带的vavr版本不一致,导致找不到CircuitBreakerRegistry.of()方法(方法参数中的io.vavr.collection.Map是旧版vavr的类型,新版已发生变更)。
改用spring-cloud-starter-circuitbreaker-resilience4j是正确选择,因为Spring Cloud BOM会自动管理兼容的Resilience4j版本,彻底避免手动引入的版本冲突问题。
二、Resilience4j未生效的核心原因及解决方案
现在启动成功但断路器不生效,主要有几个关键排查点,按优先级逐一处理:
1. 异常类型配置不匹配(最可能的根因)
你的UserInfoService使用WebClient调用外部API,当请求失败时,retrieve()方法抛出的是**WebClientResponseException**,而你配置的HttpServerErrorException是RestTemplate专属的异常类型,两者不匹配导致断路器无法识别失败请求。
修改application.yml中recordExceptions的配置,添加WebClientResponseException:
resilience4j.circuitbreaker: instances: userInfoService: # 保留原有配置 recordExceptions: - org.springframework.web.reactive.function.client.WebClientResponseException - java.io.IOException - java.util.concurrent.TimeoutException - org.springframework.web.client.ResourceAccessException - java.net.ConnectException
如果需要精准捕获5xx状态码异常,也可以在WebClient中自定义错误处理,将特定状态码转换为你配置的异常类型。
2. AOP代理模式配置问题
Spring Boot 2.6.x默认的AOP代理模式是JDK动态代理(仅代理接口),但你的UserInfoService是没有实现接口的普通类,导致AOP无法生成代理对象,@CircuitBreaker注解自然不生效。
在application.yml中添加AOP配置,强制使用CGLIB代理:
spring: aop: proxy-target-class: true
你已经引入了spring-boot-starter-aop依赖,这一步配置后就能正常生成类代理。
3. Actuator健康指标不显示的问题
你已经设置了registerHealthIndicator: true,但健康详情里没显示Resilience4j指标,可按以下步骤排查:
- 访问
/actuator/health端点,查看返回的components节点是否包含resilience4j; - 确认
spring-cloud-starter-circuitbreaker-resilience4j依赖是否正确引入(它会自动配置Resilience4j的健康指标),不要手动额外添加resilience4j-spring-boot2依赖,避免版本冲突。
4. 验证Fallback方法触发逻辑
可以先在getUserInfoById方法中手动抛出一个IOException,测试是否会进入testMethod。如果手动抛异常能触发fallback,说明之前的问题是异常类型不匹配;如果还是不触发,再重点排查AOP代理的配置是否生效。
总结
按以下顺序调整后,Resilience4j应该就能正常工作:
- 修正
recordExceptions中的异常类型,添加WebClientResponseException; - 开启CGLIB代理模式;
- 手动模拟异常验证fallback逻辑。
内容的提问来源于stack exchange,提问作者Thomson Mathew

