SpringBoot集成Resilience4j框架
Resilience4j是一个轻量级的容错库,可按需引入所需模块,避免”大而全”的问题。
提供了以下核心功能: 断路器、限流器、重试机制、隔离机制。
一、Resilience4j简介
Resilience4j核心功能:
- 断路器(Circuit Breaker)
- 限流器(Rate Limiter)
- 重试机制(Retry)
- 超时控制(Time Limiter)
- 隔离机制(Bulkhead)
- 缓存(Cache)
- 请求上下文传播(Context Propagation)
相比Netflix Hystrix和Sentinel,Resilience4j更加轻量级
二、SpringBoot集成Resilience4j步骤
1. 添加依赖
在pom.xml中添加以下依赖:
<!-- AOP支持(必须) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Resilience4j核心依赖 -->
<!-- 如果系统使用的是SpringBoot2框架,则使用resilience4j-spring-boot2,如果使用的是SpringBoot3,则使用resilience4j-spring-boot3 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.2.0</version>
</dependency>可选依赖
<!-- Spring Boot Actuator(可选,用于监控) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 不想使用resilience4j-spring-bootX集成全部组件,可单独选用下面单独的功能组件 -->
<!-- 单独使用Resilience4j Circuit Breaker监控(可选) -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 单独使用Resilience4j Retry重试(可选) -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-retry</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 单独使用Resilience4j Ratelimiter限流(可选) -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-ratelimiter</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 单独使用Resilience4j Bulkhead隔离(可选) -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
<version>2.2.0</version>
</dependency>2. 配置Resilience4j
可在application.yml中添加配置:
resilience4j:
# 断路器配置
circuitbreaker:
instances:
backendA:
# 注册健康指标(可通过/actuator/health监控)
registerHealthIndicator: true
# 滑动窗口大小为10次调用
slidingWindowSize: 10
# 至少5次调用后才计算失败率
minimumNumberOfCalls: 5
# HALF_OPEN状态下允许3次试探调用
permittedNumberOfCallsInHalfOpenState: 3
# 自动从OPEN转为HALF_OPEN
automaticTransitionFromOpenToHalfOpenEnabled: true
# OPEN状态持续5秒后自动转为HALF_OPEN
waitDurationInOpenState: 5s
# 失败率超过50%时跳闸(默认50%)
failureRateThreshold: 50
# 事件缓冲区大小(用于监听状态变更事件)
eventConsumerBufferSize: 10
# 触发断路器计数的异常
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
- java.util.concurrent.TimeoutException
- org.springframework.web.client.ResourceAccessException
# 忽略的异常(不触发断路器)
ignoreExceptions:
- com.example.demo.BusinessException
# 重试机制配置
retry:
instances:
backendA:
# 最大重试次数(含首次调用)
maxAttempts: 3
# 每次重试间隔100ms
waitDuration: 100ms
# 仅对以下异常重试
retryExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
# 超时配置
timelimiter:
instances:
backendA:
# 方法调用超时时间为2秒
timeoutDuration: 2s
# 限流配置
ratelimiter:
instances:
backendA:
# 每秒最多10次请求
limitForPeriod: 10
# 限流周期为1秒
limitRefreshPeriod: 1s
# 请求超过限流时,最多等待100ms
timeoutDuration: 100ms
# 隔离配置
bulkhead:
instances:
backendA:
# 最大并发调用数10
maxConcurrentCall: 10
# 请求超过并发数时,最多等待10ms
maxWaitDuration: 10ms三、Resilience4j使用案例
1. 断路器(Circuit Breaker)案例
CircuitBreaker断路器是由一个有限状态机实现的,
其包含三个一般性状态: CLOSED(关闭) , OPEN(打开) , HALF_OPEN(半开)
CLOSED (关闭):说明断路器是关闭的,服务调用是正常的。
OPEN (打开):说明断路器是打开的,表示调用的服务出现了异常,会暂停调用服务,转为执行指定的服务降级方法。
HALF_OPEN (半开):此时断路器处于运行状态,但是还是会允许一定数量的请求,去调用服务,其他的请求,转为执行指定的服务降级方法。(例:一共有100个请求,现在断路器状态为半开,那么此时就只允许10个请求去调用服务,其他90个请求去执行降级方法)(允许请求的数量由配置属性permittedNumberOfCalls InHalfOpenState控制)
和两个特定状态: DISABLED(禁用) , FORCED_OPEN(强开) 。
DISABLED(禁用) : 断路器被禁用,即使服务调用失败,也不会触发熔断或 fallback;
FORCED_OPEN(强开) : 断路器被强制打开,所有请求都会直接触发 fallback;
配置信息
resilience4j:
# 断路器配置
circuitbreaker:
instances:
backendA:
# 注册健康指标(可通过/actuator/health监控)
registerHealthIndicator: true
# 滑动窗口大小为10次调用
slidingWindowSize: 10
# 至少5次调用后才计算失败率
minimumNumberOfCalls: 5
# HALF_OPEN状态下允许的最大请求试探调用数量
permittedNumberOfCallsInHalfOpenState: 3
# 自动从OPEN转为HALF_OPEN
automaticTransitionFromOpenToHalfOpenEnabled: true
# OPEN状态持续5秒后自动转为HALF_OPEN
waitDurationInOpenState: 5s
# 失败率超过50%时跳闸(默认50%)
failureRateThreshold: 50
# 事件缓冲区大小(用于监听状态变更事件)
eventConsumerBufferSize: 10
# 触发断路器计数的异常
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
- java.util.concurrent.TimeoutException
- org.springframework.web.client.ResourceAccessException
# 忽略的异常(不触发断路器)
ignoreExceptions:
- com.example.demo.BusinessException代码案例
@Service
public class ExternalApiService {
private final RestTemplate restTemplate;
public ExternalApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@CircuitBreaker(name = "backendA", fallbackMethod = "fallback")
public String callExternalApi(String param) {
return restTemplate.getForObject("http://external-service/api?param=" + param, String.class);
}
private String fallback(String param, Exception e) {
return "Fallback response for " + param;
}
}行为逻辑
当
backendA方法的调用失败(抛出recordExceptions配置中的异常)达到 5次调用中50%失败率(即至少3次失败),断路器跳闸为 OPEN 状态。在 OPEN 状态下,所有的请求都会被直接拒绝,然后走
fallback方法。在持续 5秒 后会自动转为 HALF_OPEN由
automaticTransitionFromOpenToHalfOpenEnabled配置是否自动从OPEN转为HALF_OPEN;由
waitDurationInOpenState配置控制OPEN状态持续多久后自动转为HALF_OPEN;
HALF_OPEN 状态下允许 3次试探调用 (由
permittedNumberOfCallsInHalfOpenState配置控制),若成功则恢复为 CLOSED,否则重回 OPEN。
2. 重试(Retry)案例
配置信息
resilience4j:
# 重试机制配置
retry:
instances:
backendA:
max-attempts: 3 # 最大重试次数(包含首次调用)
wait-duration:
seconds: 1 # 每次重试间隔1秒
retry-exceptions: # 仅对以下设置的异常进行重试
- java.lang.RuntimeException代码案例
@Service
public class PaymentService {
@Retry(name = "backendA", fallbackMethod = "fallback")
public String processPayment(String paymentInfo) {
// 模拟可能失败的操作
if (Math.random() > 0.7) {
throw new RuntimeException("Payment processing failed");
}
return "Payment processed successfully: " + paymentInfo;
}
private String fallback(String paymentInfo, RuntimeException e) {
return "Payment fallback after retries: " + paymentInfo;
}
}行为逻辑
- 当方法抛出
RuntimeException异常时,最多重试 3次(首次调用 + 2次重试),每次间隔 1s (如果不是RuntimeException异常,则不会进行重试)。 - 如果重试后仍失败,异常会传递给上层(如触发断路器计数或
fallback)。
3. 限流(Rate Limiter)案例
配置信息
ratelimiter:
instances:
testRateLimiter:
limit-for-period: 2 # 每秒最多10次请求
limit-refresh-period: 500ms # 限流周期为1秒
timeout-duration: 0 # 请求超过限流时,最多等待3s代码案例
@Service
public class NotificationService {
@RateLimiter(name = "backendA", fallbackMethod = "fallback")
public String sendNotification(String message) {
// 发送通知逻辑
return "Notification sent: " + message;
}
private String fallback(String message, io.github.resilience4j.ratelimiter.RequestNotPermitted e) {
return "Notification request rate limit exceeded for: " + message;
}
}行为逻辑
- 每秒钟允许最多 10次 调用,超过的请求会等待 100ms。
- 如果等待后仍无法获取许可,抛出
RequestNotPermitted异常(需自行处理或配置fallback)。
4. 隔离(Bulkhead)案例
没用过,暂不记录
5. 组合使用多个Resilience4j模块
当所有模块同时作用于 backendA 方法时,执行顺序如下:
Bulkhead 检查并发数 → RateLimiter 检查限流 → TimeLimiter 开始计时 → Retry 在失败时重试 → CircuitBreaker 统计失败率并决定是否跳闸
@Service
public class OrderService {
@Bulkhead(name = "backendA", type = Bulkhead.Type.SEMAPHORE)
@TimeLimiter(name = "backendA")
@CircuitBreaker(name = "backendA", fallbackMethod = "fallback")
@Retry(name = "backendA", fallbackMethod = "fallback")
public CompletableFuture<String> processOrder(Order order) {
return CompletableFuture.supplyAsync(() -> {
// 处理订单逻辑
if (Math.random() > 0.8) {
throw new RuntimeException("Order processing failed");
}
return "Order processed: " + order.getId();
});
}
private CompletableFuture<String> fallback(Order order, Exception e) {
return CompletableFuture.completedFuture("Fallback order processing for: " + order.getId());
}
}四、监控与指标
Resilience4j可以与Spring Boot Actuator集成,提供监控端点:
- 添加Actuator配置:
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: health,metrics,circuitbreakers- 访问监控端点:
/actuator/health- 查看健康状态/actuator/metrics- 查看指标/actuator/circuitbreakers- 查看断路器状态
五、最佳实践
- 合理配置参数:根据实际业务场景调整滑动窗口大小、失败率阈值等参数
- 选择合适的异常:只对可重试的异常配置重试机制
- 设计有意义的fallback:fallback方法应提供合理的降级响应
- 监控和告警:结合Prometheus和Grafana建立监控体系
- 避免过度使用:不是所有方法都需要添加Resilience4j装饰
六、总结
Resilience4j为SpringBoot应用提供了强大的容错能力,通过简单的注解即可实现断路器、重试、限流等功能。合理使用Resilience4j可以显著提高系统的稳定性和可靠性,特别是在微服务架构中面对不稳定的外部依赖时。
疑问
重试(Retry)和事务结合使用时,事务会正常回滚吗?(待验证)
