tacit/resilience4j-usage-template.md

382 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Resilience4j 使用模板与文档
## 1. 概述
Resilience4j 是一个轻量级的容错库,专为 Java 8+ 和函数式编程设计。它提供了断路器、限流、重试、舱壁隔离和超时控制等功能,帮助构建弹性和可靠的系统。
## 2. 配置文件示例
### 2.1 application.yml 配置
```yaml
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 层使用示例
```java
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 层使用示例
```java
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 回退方法注意事项
1. 回退方法必须与原始方法在同一个类中
2. 回退方法的参数列表必须与原始方法相同,并且最后一个参数是 Throwable 类型
3. 回退方法的返回类型必须与原始方法相同
4. 异步方法的回退方法必须返回 CompletableFuture
### 4.3 监控与指标
Resilience4j 提供了与 Micrometer 和 Prometheus 的集成,可以监控各种指标:
```yaml
# 启用 Resilience4j 指标management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
```
## 5. 最佳实践
1. **合理配置参数**:根据实际业务场景调整各功能的参数
2. **使用回退策略**:为每个容错功能提供适当的回退方法
3. **监控与告警**:定期监控各功能的指标,设置合理的告警阈值
4. **组合使用**:根据需求组合使用多个容错功能
5. **异常处理**:区分可重试和不可重试的异常类型
6. **性能测试**:在生产环境部署前进行充分的性能测试
## 6. 常见问题与解决方案
### 6.1 断路器一直处于打开状态
- 检查失败率阈值是否设置过低
- 检查是否有足够的请求数触发断路器
- 检查忽略的异常类型是否正确
### 6.2 限流不生效
- 检查限流配置是否正确
- 检查限流实例名称是否与注解中的名称一致
- 检查是否有其他限流机制影响
### 6.3 重试不生效
- 检查重试的异常类型是否正确
- 检查重试次数和间隔是否合理
- 检查是否有其他重试机制影响
## 7. 依赖管理
如果使用 Spring Boot可以只引入以下依赖
```xml
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>${resilience4j.version}</version>
</dependency>
```
如果需要更精细的控制,可以单独引入所需的模块:
```xml
<!-- 核心模块 -->
<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 版本。