微服务架构设计模式系列(三):可靠性篇-容错模式
微服务架构中,服务之间高度依赖。一个微小的故障可能会在系统中 连锁反应,最终导致级联失败。
为了增强系统的 容错性与鲁棒性,业界总结了多种模式。这里我们重点介绍 断路器、舱壁隔离、超时与重试 三种。
1. Circuit Breaker(断路器)
场景
当下游服务频繁失败时,直接“熔断”请求,避免无限重试拖垮整个系统。
实现(基于 Resilience4j)
<!-- pom.xml 引入依赖 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
@Service
public class UserClient {
private final WebClient webClient;
public UserClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("http://userservice:8081").build();
}
@CircuitBreaker(name = "userService", fallbackMethod = "fallbackUser")
public Mono<User> getUser(Long id) {
return webClient.get()
.uri("/users/{id}", id)
.retrieve()
.bodyToMono(User.class);
}
// 熔断时的兜底逻辑
public Mono<User> fallbackUser(Long id, Throwable ex) {
return Mono.just(new User(id, "Guest", "guest@example.com"));
}
}
# application.yml 配置熔断规则
resilience4j:
circuitbreaker:
instances:
userService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 10s
这段YAML配置代码用于设置Resilience4j的熔断器功能:
- 功能:为服务实例配置熔断机制
- slidingWindowSize:滑动窗口大小为10个请求
- failureRateThreshold:失败率阈值为50%,超过则触发熔断
- waitDurationInOpenState:熔断器开启状态持续10秒后进入半开状态
当服务请求失败率超过50%时,熔断器会自动切换到开启状态,暂停请求转发10秒钟,防止故障扩散。
2. Bulkhead(舱壁隔离)
场景
防止某个依赖“独占”线程资源,把服务拉垮。像船舱隔板一样,把资源隔离开。
实现(线程池隔离)
@Service
public class InventoryClient {
private final WebClient webClient;
public InventoryClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("http://inventoryservice:8083").build();
}
@Bulkhead(name = "inventoryService", type = Bulkhead.Type.THREADPOOL)
public Mono<String> checkStock(Long productId) {
return webClient.get()
.uri("/inventory/{id}", productId)
.retrieve()
.bodyToMono(String.class);
}
}
resilience4j:
thread-pool-bulkhead:
instances:
inventoryService:
maxThreadPoolSize: 5
coreThreadPoolSize: 3
queueCapacity: 10
这段YAML代码配置了一个名为inventoryService的线程池隔离实例:
maxThreadPoolSize: 5:最大线程数为5coreThreadPoolSize: 3:核心线程数为3queueCapacity: 10:等待队列容量为10
用于控制并发访问库存服务的线程数量,防止服务过载。
这样,当库存服务阻塞时,只会占用有限线程,不会拖垮整个应用。
3. Timeout & Retry(超时与重试)
场景
网络请求可能因为抖动失败。合理设置 超时 与 有限重试 能提高成功率。
实现(Resilience4j Timeout + Retry)
@Service
public class PaymentClient {
private final WebClient webClient;
public PaymentClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("http://paymentservice:8084").build();
}
@Retry(name = "paymentService")
@TimeLimiter(name = "paymentService")
public CompletableFuture<String> processPayment(Long orderId) {
return webClient.post()
.uri("/pay/{id}", orderId)
.retrieve()
.bodyToMono(String.class)
.toFuture();
}
}
resilience4j:
retry:
instances:
paymentService:
maxAttempts: 3
waitDuration: 2s
timelimiter:
instances:
paymentService:
timeoutDuration: 3s
这段YAML配置代码定义了名为paymentService的服务重试和超时策略:
- 重试配置:最多尝试3次,每次等待2秒
- 超时配置:每次调用超时时间为3秒
通过resilience4j框架实现服务的容错处理,提升系统稳定性。
4. 综合应用
在真实微服务项目中,通常会同时使用:
- 断路器 → 保护依赖服务不稳定时的调用。
- 舱壁隔离 → 防止某个依赖消耗过多资源。
- 超时 + 重试 → 避免因网络抖动带来的失败。
这些模式组合起来,可以大幅提升系统的 鲁棒性与容错能力。
168万+

被折叠的 条评论
为什么被折叠?



