11 KiB
11 KiB
Resilience4j 使用模板与文档
1. 概述
Resilience4j 是一个轻量级的容错库,专为 Java 8+ 和函数式编程设计。它提供了断路器、限流、重试、舱壁隔离和超时控制等功能,帮助构建弹性和可靠的系统。
2. 配置文件示例
2.1 application.yml 配置
resilience4j:
# 断路器配置
circuitbreaker:
instances:
userServiceCircuitBreaker:
# 失败阈值百分比
failureRateThreshold: 50
# 滑动窗口类型(count-based 或 time-based)
slidingWindowType: COUNT_BASED
# 滑动窗口大小
slidingWindowSize: 10
# 最小请求数
minimumNumberOfCalls: 5
# 半开状态下允许的最大请求数
permittedNumberOfCallsInHalfOpenState: 3
# 等待时间(毫秒)
waitDurationInOpenState: 10000
# 自动从半开状态恢复到关闭状态
automaticTransitionFromOpenToHalfOpenEnabled: true
# 忽略的异常类型
ignoreExceptions:
- org.springframework.web.client.HttpClientErrorException$BadRequest
# 限流配置
ratelimiter:
instances:
userServiceRateLimiter:
# 每秒允许的请求数
limitForPeriod: 100
# 时间窗口(毫秒)
limitRefreshPeriod: 1000
# 等待获取许可的超时时间(毫秒)
timeoutDuration: 500
# 重试配置
retry:
instances:
userServiceRetry:
# 最大重试次数
maxAttempts: 3
# 初始重试间隔(毫秒)
waitDuration: 1000
# 重试退避策略
retryExponentialBackoff:
initialInterval: 1000
multiplier: 2
maxInterval: 10000
# 重试的异常类型
retryExceptions:
- org.springframework.web.client.HttpServerErrorException
# 忽略的异常类型
ignoreExceptions:
- org.springframework.web.client.HttpClientErrorException$BadRequest
# 舱壁配置
bulkhead:
instances:
userServiceBulkhead:
# 最大并行执行的任务数
maxConcurrentCalls: 20
# 等待队列大小
maxWaitDuration: 1000
# 超时控制配置
timelimiter:
instances:
userServiceTimeLimiter:
# 超时时间(毫秒)
timeoutDuration: 3000
3. 使用示例
3.1 Service 层使用示例
package com.tacit.admin.service.impl;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.retry.annotation.Retry;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.CompletableFuture;
@Service
public class UserService {
private final RestTemplate restTemplate;
public UserService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* 使用断路器示例
* @param userId 用户ID
* @return 用户信息
*/
@CircuitBreaker(
name = "userServiceCircuitBreaker",
fallbackMethod = "getUserFallback"
)
public String getUserById(Long userId) {
return restTemplate.getForObject("http://user-service/users/{id}", String.class, userId);
}
/**
* 使用限流示例
* @param userId 用户ID
* @return 用户信息
*/
@RateLimiter(
name = "userServiceRateLimiter",
fallbackMethod = "getUserFallback"
)
public String getUserWithRateLimit(Long userId) {
return restTemplate.getForObject("http://user-service/users/{id}", String.class, userId);
}
/**
* 使用重试示例
* @param userId 用户ID
* @return 用户信息
*/
@Retry(
name = "userServiceRetry",
fallbackMethod = "getUserFallback"
)
public String getUserWithRetry(Long userId) {
return restTemplate.getForObject("http://user-service/users/{id}", String.class, userId);
}
/**
* 使用舱壁示例
* @param userId 用户ID
* @return 用户信息
*/
@Bulkhead(
name = "userServiceBulkhead",
fallbackMethod = "getUserFallback"
)
public String getUserWithBulkhead(Long userId) {
return restTemplate.getForObject("http://user-service/users/{id}", String.class, userId);
}
/**
* 使用超时控制示例
* @param userId 用户ID
* @return 用户信息
*/
@TimeLimiter(
name = "userServiceTimeLimiter",
fallbackMethod = "getUserAsyncFallback"
)
public CompletableFuture<String> getUserWithTimeout(Long userId) {
return CompletableFuture.supplyAsync(() ->
restTemplate.getForObject("http://user-service/users/{id}", String.class, userId)
);
}
/**
* 组合使用多个功能示例
* @param userId 用户ID
* @return 用户信息
*/
@CircuitBreaker(
name = "userServiceCircuitBreaker",
fallbackMethod = "getUserFallback"
)
@Retry(
name = "userServiceRetry"
)
@RateLimiter(
name = "userServiceRateLimiter"
)
public String getUserWithMultipleFeatures(Long userId) {
return restTemplate.getForObject("http://user-service/users/{id}", String.class, userId);
}
/**
* 同步回退方法
* @param userId 用户ID
* @param ex 异常
* @return 回退结果
*/
private String getUserFallback(Long userId, Exception ex) {
return "{\"id\":0,\"name\":\"Fallback User\",\"message\":\"服务暂时不可用,请稍后重试\"}";
}
/**
* 异步回退方法
* @param userId 用户ID
* @param ex 异常
* @return 回退结果
*/
private CompletableFuture<String> getUserAsyncFallback(Long userId, Exception ex) {
return CompletableFuture.completedFuture(
"{\"id\":0,\"name\":\"Async Fallback User\",\"message\":\"服务暂时不可用,请稍后重试\"}"
);
}
}
3.2 Controller 层使用示例
package com.tacit.admin.controller;
import com.tacit.admin.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理相关接口")
public class UserController {
@Autowired
private UserService userService;
@Operation(summary = "获取用户信息", description = "使用断路器模式获取用户信息")
@GetMapping("/get/{id}")
public String getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
@Operation(summary = "限流获取用户信息", description = "使用限流模式获取用户信息")
@GetMapping("/rate-limit/{id}")
public String getUserWithRateLimit(@PathVariable Long id) {
return userService.getUserWithRateLimit(id);
}
@Operation(summary = "重试获取用户信息", description = "使用重试模式获取用户信息")
@GetMapping("/retry/{id}")
public String getUserWithRetry(@PathVariable Long id) {
return userService.getUserWithRetry(id);
}
@Operation(summary = "超时控制获取用户信息", description = "使用超时控制获取用户信息")
@GetMapping("/timeout/{id}")
public CompletableFuture<String> getUserWithTimeout(@PathVariable Long id) {
return userService.getUserWithTimeout(id);
}
@Operation(summary = "组合功能获取用户信息", description = "组合使用多个容错功能获取用户信息")
@GetMapping("/multiple/{id}")
public String getUserWithMultipleFeatures(@PathVariable Long id) {
return userService.getUserWithMultipleFeatures(id);
}
}
4. 使用说明
4.1 注解说明
| 注解 | 功能 | 主要属性 |
|---|---|---|
@CircuitBreaker |
断路器 | name, fallbackMethod |
@RateLimiter |
限流 | name, fallbackMethod |
@Retry |
重试 | name, fallbackMethod |
@Bulkhead |
舱壁隔离 | name, fallbackMethod, type |
@TimeLimiter |
超时控制 | name, fallbackMethod |
4.2 回退方法注意事项
- 回退方法必须与原始方法在同一个类中
- 回退方法的参数列表必须与原始方法相同,并且最后一个参数是 Throwable 类型
- 回退方法的返回类型必须与原始方法相同
- 异步方法的回退方法必须返回 CompletableFuture
4.3 监控与指标
Resilience4j 提供了与 Micrometer 和 Prometheus 的集成,可以监控各种指标:
# 启用 Resilience4j 指标management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
5. 最佳实践
- 合理配置参数:根据实际业务场景调整各功能的参数
- 使用回退策略:为每个容错功能提供适当的回退方法
- 监控与告警:定期监控各功能的指标,设置合理的告警阈值
- 组合使用:根据需求组合使用多个容错功能
- 异常处理:区分可重试和不可重试的异常类型
- 性能测试:在生产环境部署前进行充分的性能测试
6. 常见问题与解决方案
6.1 断路器一直处于打开状态
- 检查失败率阈值是否设置过低
- 检查是否有足够的请求数触发断路器
- 检查忽略的异常类型是否正确
6.2 限流不生效
- 检查限流配置是否正确
- 检查限流实例名称是否与注解中的名称一致
- 检查是否有其他限流机制影响
6.3 重试不生效
- 检查重试的异常类型是否正确
- 检查重试次数和间隔是否合理
- 检查是否有其他重试机制影响
7. 依赖管理
如果使用 Spring Boot,可以只引入以下依赖:
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>${resilience4j.version}</version>
</dependency>
如果需要更精细的控制,可以单独引入所需的模块:
<!-- 核心模块 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-core</artifactId>
<version>${resilience4j.version}</version>
</dependency>
<!-- 各功能模块 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>${resilience4j.version}</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-ratelimiter</artifactId>
<version>${resilience4j.version}</version>
</dependency>
<!-- 其他模块... -->
8. 版本兼容
| Resilience4j 版本 | Spring Boot 版本 | Java 版本 |
|---|---|---|
| 2.x | 3.x | 17+ |
| 1.x | 2.x | 8+ |
请根据您的 Spring Boot 版本选择合适的 Resilience4j 版本。