更新时间:2025-01-09 GMT+08:00
熔断器打开,导致方法调用失败
问题描述
熔断器打开,导致方法调用失败。
解决方案
- 在没有使用自定义降级方法和缓存的时候,原方法如果调用失败会抛出方法原始出的错误。
- 如果使用了自定义降级方法。
- 熔断前:自定义降级方法中添加的最后一个异常的参数封装的就是原方法的异常。
- 熔断后:最后一个异常参数会固定抛出“io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'xxxxx#xxxxx' is OPEN and does not permit further calls”异常。
可以通过这个异常参数找到熔断的原因,如果日志过大,找不到熔断前的日志,可以对异常参数类型做个判断,将CallNotPermittedException异常和其他异常区别打印,这样更方便定位问题。如下所示:
public String myFallBack(long sleepTime, Throwable throwable) { if (throwable instanceof CallNotPermittedException) { log.info("clientcontrol call not permited exception ", throwable); } else { log.info("service exception " , throwable); } return "xxxx"; }
熔断器的状态变化会打印相应的日志,日志中关键信息如下:
- 关闭到打开(此时处于熔断状态,方法不可访问):changed state from CLOSED to OPEN。
- 打开到半开(方法可以访问):changed state from OPEN to HALF_OPEN。
- 半开到打开(此时处于熔断状态,方法不可访问):changed state from HALF_OPEN to OPEN。
- 半开到关闭(方法恢复正常,可以访问):changed state from HALF_OPEN to CLOSED。
如果日志中找不到原方法的报错信息,只能找到“io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'xxxxx#xxxxx' is OPEN and does not permit further calls”这种日志,需要排查clientcontrol的配置文件,看是否开启了慢调用熔断,如果开启了慢调用熔断,会出现原方法没有报出异常,也被熔断的现象。慢调用的配置参数如下:devspore: client-control: rules: xxx: fallback: #慢调用时间(超过即为慢调用,单位s,默认60S) slow-call-duration-threshold: 60 #慢调用熔断比例(慢调用数量达到比例则熔断,默认100等于关闭状态) slow-call-rate-threshold: 100
父主题: 常见问题