微服务稳定性治理的限流熔断需求
在高并发设计和微服务架构中,服务间调用链路任何一个节点的性能劣化都可能引发雪崩效应。限流控制请求速率防止服务过载,熔断在下游故障时快速失败避免资源耗尽,降级在不可用时返回兜底响应。Spring Boot 3.x时代,Resilience4j已成为Spring Cloud CircuitBreaker的默认实现,Sentinel作为阿里开源方案在国内也有广泛使用。两者在服务治理领域的定位和实现策略有显著差异。
Resilience4j核心组件与配置
Resilience4j基于函数式编程设计,提供CircuitBreaker、RateLimiter、Retry、Bulkhead、TimeLimiter等模块。Spring Boot 3集成方式:
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.2.0</version>
</dependency>
application.yml配置:
resilience4j:
circuitbreaker:
configs:
default:
sliding-window-type: COUNT_BASED
sliding-window-size: 100
minimum-number-of-calls: 10
failure-rate-threshold: 50
slow-call-rate-threshold: 60
slow-call-duration-threshold: 2s
wait-duration-in-open-state: 30s
permitted-number-of-calls-in-half-open-state: 10
automatic-transition-from-open-to-half-open-enabled: true
instances:
productService:
base-config: default
orderService:
base-config: default
ratelimiter:
configs:
default:
limit-for-period: 100
limit-refresh-period: 1s
timeout-duration: 0
instances:
productService:
base-config: default
apiGateway:
base-config: default
retry:
configs:
default:
max-attempts: 3
wait-duration: 500ms
retry-exceptions:
- java.io.IOException
- java.util.concurrent.TimeoutException
instances:
productService:
base-config: default
bulkhead:
configs:
default:
max-concurrent-calls: 20
max-wait-duration: 0
instances:
productService:
base-config: default
注解方式使用CircuitBreaker
Spring Boot 3中通过注解声明式使用Resilience4j:
@Service
public class OrderService {
@CircuitBreaker(name = "productService", fallbackMethod = "fallbackGetProduct")
@RateLimiter(name = "productService")
@Retry(name = "productService")
@Bulkhead(name = "productService")
public Product getProduct(Long productId) {
// 调用商品服务
return restTemplate.getForObject(
"http://product-service/api/products/" + productId,
Product.class
);
}
// 熔断/限流/重试时的兜底方法
// 参数签名需与原方法一致,末尾追加异常参数
private Product fallbackGetProduct(Long productId, Exception e) {
// 返回缓存或默认值
Product cached = cacheManager.getCache("products")
.get(productId, Product.class);
if (cached != null) {
return cached;
}
return Product.builder()
.id(productId)
.name("商品信息暂时不可用")
.available(false)
.build();
}
}
注解可以组合使用,执行顺序为Retry → CircuitBreaker → RateLimiter → Bulkhead → 实际方法调用。这个顺序确保在限流和熔断之前先尝试重试,避免对已熔断的服务发起无效重试。
函数式API与自定义组合
对于需要精细控制的场景,Resilience4j提供函数式API:
@Configuration
public class ResilienceConfig {
@Bean
public CircuitBreakerRegistry circuitBreakerRegistry() {
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.slidingWindowType(SlidingWindowType.COUNT_BASED)
.slidingWindowSize(100)
.failureRateThreshold(50)
.slowCallRateThreshold(60)
.slowCallDurationThreshold(Duration.ofSeconds(2))
.waitDurationInOpenState(Duration.ofSeconds(30))
.permittedNumberOfCallsInHalfOpenState(10)
.registerHealthIndicator(true)
.recordExceptions(IOException.class, TimeoutException.class)
.ignoreExceptions(BusinessException.class) // 业务异常不计入熔断
.build();
return CircuitBreakerRegistry.of(config);
}
@Bean
public RateLimiterRegistry rateLimiterRegistry() {
RateLimiterConfig config = RateLimiterConfig.custom()
.limitForPeriod(100)
.limitRefreshPeriod(Duration.ofSeconds(1))
.timeoutDuration(Duration.ZERO) // 超限立即拒绝
.build();
return RateLimiterRegistry.of(config);
}
}
// 函数式组合使用
@Service
public class PaymentService {
private final CircuitBreaker circuitBreaker;
private final RateLimiter rateLimiter;
private final Bulkhead bulkhead;
public PaymentService(CircuitBreakerRegistry cbRegistry,
RateLimiterRegistry rlRegistry) {
this.circuitBreaker = cbRegistry.circuitBreaker("paymentService");
this.rateLimiter = rlRegistry.rateLimiter("paymentService");
this.bulkhead = Bulkhead.of("paymentService",
BulkheadConfig.custom().maxConcurrentCalls(20).build());
}
// 装饰器模式组合多个组件
public PaymentResult processPayment(PaymentRequest request) {
Supplier<PaymentResult> supplier = () -> callPaymentApi(request);
// 组合顺序:Bulkhead → RateLimiter → CircuitBreaker
Supplier<PaymentResult> decorated = Decorators.ofSupplier(supplier)
.withBulkhead(bulkhead)
.withRateLimiter(rateLimiter)
.withCircuitBreaker(circuitBreaker)
.withFallback(List.of(IOException.class, TimeoutException.class),
e -> PaymentResult.failed("支付服务暂时不可用"))
.decorate();
return decorated.get();
}
}
Sentinel流量治理方案
Sentinel采用滑动窗口统计 + 令牌桶限流,与Resilience4j的漏桶限流有本质区别。Spring Boot 3集成:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2023.0.1.0</version>
</dependency>
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8858 # Sentinel控制台地址
port: 8719 # 客户端与控制台通信端口
eager: true # 应用启动即连接控制台
// 注解方式定义资源
@SentinelResource(
value = "queryProduct",
blockHandler = "blockHandler",
fallback = "fallbackHandler"
)
public Product queryProduct(Long id) {
return restTemplate.getForObject(
"http://product-service/api/products/" + id, Product.class);
}
// 限流/熔断时的处理
public Product blockHandler(Long id, BlockException e) {
return Product.defaultUnavailable();
}
// 业务异常时的降级
public Product fallbackHandler(Long id, Throwable t) {
return Product.builder()
.id(id)
.name("服务降级")
.build();
}
Sentinel的优势在于可视化控制台,支持运行时动态修改限流规则,无需重启应用。
Resilience4j与Sentinel对比分析
| 维度 | Resilience4j | Sentinel |
|---|---|---|
| 限流算法 | 基于AtomicReference的令牌桶 | 滑动窗口+令牌桶 |
| 熔断策略 | 异常比例/慢调用比例 | 异常比例/慢调用/异常数 |
| 动态规则 | 需配合Archaius或自定义配置源 | 内置控制台动态推送 |
| 系统自适应 | 不支持 | 支持(CPU/RT/线程数自适应限流) |
| 框架依赖 | 轻量,Vavr函数式库 | 较重,需部署Dashboard |
| Spring生态 | Spring Cloud默认实现 | Spring Cloud Alibaba |
分布式事务中的熔断配置
在API接口规范和消息中间件场景中,熔断配置需要特别处理超时与重试的关系:
// 分布式事务场景下的熔断配置
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> customizer() {
return factory -> {
// 全局默认配置
factory.configureDefault(id -> new Resilience4JConfig.Builder(id)
.timeLimiterConfig(TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(3))
.build())
.circuitBreakerConfig(CircuitBreakerConfig.custom()
.slidingWindowSize(20)
.failureRateThreshold(50)
.waitDurationInOpenState(Duration.ofSeconds(20))
.build())
.build());
// 针对特定服务的定制配置
factory.configure(new Resilience4JConfig.Builder("orderService")
.timeLimiterConfig(TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(5)) // 订单服务允许更长时间
.build())
.circuitBreakerConfig(CircuitBreakerConfig.custom()
.failureRateThreshold(30) // 订单服务更敏感,30%即熔断
.waitDurationInOpenState(Duration.ofSeconds(60))
.build())
.build(), "orderService");
};
}
监控指标与健康检查
Resilience4j通过Actuator暴露熔断器状态指标:
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,circuitbreakers
endpoint:
health:
show-details: always
health:
circuitbreakers:
enabled: true
# 访问指标
# GET /actuator/circuitbreakers - 熔断器状态概览
# GET /actuator/metrics/resilience4j.circuitbreaker.state - 各熔断器状态
# GET /actuator/metrics/resilience4j.circuitbreaker.calls - 调用统计
这些指标可以接入Prometheus,在Grafana中配置告警:当熔断器处于OPEN状态时触发告警,持续超过5分钟升级为P1级别。业务中台建设中,这种监控指标是评估服务可用性和制定SLA标准的基础数据。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot3-wei-fu-wu-xian-liu-rong-duan-shi-zhan/