微服务架构里,下游接口超时或故障会顺着调用链向上蔓延,熔断降级是切断这条链路的标准手段。Resilience4j是Spring Cloud中默认的容错组件,按circuit breaker、bulkhead、retry、rate limiter四类策略分别生效。本文给出在Spring Boot 3.x里把熔断器真正跑起来的配置与验证方法。
Resilience4j的熔断器原理
熔断器维护三种状态:CLOSED(正常放行)、OPEN(熔断拒绝)、HALF_OPEN(半开试探)。滑动窗口统计最近N次调用的失败率,超过阈值进入OPEN;熔断窗口结束后进入HALF_OPEN,放行少量试探请求,成功则恢复CLOSED,失败则回到OPEN。
resilience4j.circuitbreaker:
instances:
order-service:
slidingWindowSize: 20
failureRateThreshold: 50
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 5
minimumNumberOfCalls: 5
最近20次调用里至少5次统计,错误率超过50%熔断10秒。minimumNumberOfCalls避免调用量太小就误触发。
服务端接入熔断器
@Service
public class OrderClient {
@Autowired
private RestTemplate restTemplate;
@CircuitBreaker(name = "order-service", fallbackMethod = "orderFallback")
public String fetchOrder(Long id) {
return restTemplate.getForObject(
"http://order-service/api/order/" + id, String.class);
}
public String orderFallback(Long id, Throwable t) {
return "{"code":503,"msg":"order service unavailable"}";
}
}
fallbackMethod的返回值类型要和原方法一致,第二个参数可以接收异常对象用于日志。fallback本身要保持轻量,不要再发网络请求,否则退化逻辑也会拖垮线程。
线程隔离与信号量隔离的选择
resilience4j.bulkhead:
instances:
order-service:
maxConcurrentCalls: 20
maxWaitDuration: 500ms
Resilience4j默认用信号量隔离(SemaphoreBulkhead),只限制并发数不额外消耗线程,适合IO密集型但延迟可控的场景。ThreadPoolBulkhead需要为每个实例分配线程池,隔离性更强但开销更大。多数业务先上信号量,线程池隔离在核心链路上再用。
重试与熔断的组合顺序
重试要和熔断错开:先重试几次吸收瞬时抖动,再熔断保护下游。
resilience4j.retry:
instances:
order-service:
maxAttempts: 2
waitDuration: 500ms
retryExceptions:
- java.net.ConnectException
- java.net.SocketTimeoutException
重试只对连接异常、超时这类可重试错误生效,业务校验类异常不要重试。调用链上的注解顺序里,@Retry放外层、@CircuitBreaker放内层,这样熔断判断在重试之后,避免重试直接打穿熔断器。
熔断指标观测与阈值调参
引入actuator和micrometer,把熔断器状态暴露给Prometheus:
management.endpoints.web.exposure.include: health,circuitbreakers
management.metrics.distribution.sliding-window.enabled: true
上线初期把failureRateThreshold调到60%到70%观察基线,运行稳定后再收紧到50%。熔断器的每个参数变更都要有依据,调用量、错误率、P99延迟的监控数据是唯一的判断来源。熔断降级配置完之后,用故障注入工具定期演练,验证fallback真实生效。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/wei-fu-wu-rong-duan-jiang-ji-shi-zhan-resilience4j-zai/