微服务限流熔断的必要性
微服务架构下,服务间的调用链路比单体应用复杂得多。一个下游服务的响应变慢或不可用,会通过线程池耗尽、连接超时等机制向上游传播,最终导致整个调用链雪崩。后端开发中限流和熔断是应对此类问题的两道防线——限流控制进入系统的请求量,熔断在故障发生时快速切断调用。
Spring Boot微服务中,Sentinel是Alibaba开源的流量防护组件,提供了限流、熔断、系统保护、热点参数限流等完整能力,与Spring Cloud生态集成度高,且支持集群限流模式。相比Hystrix(已停止维护),Sentinel的规则配置更细粒度,支持热加载和持久化。
Sentinel核心概念与规则配置
Sentinel的资源(Resource)是防护的基本单位,可以是接口、方法或代码块。规则(Rule)定义了对资源的防护策略,包括流控规则、熔断规则、系统规则和授权规则。
Spring Boot集成Sentinel的依赖配置:
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.8</version>
</dependency>
<!-- Sentinel Dashboard通信 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.8</version>
</dependency>
流控规则配置——QPS限流和线程数限流:
@Configuration
public class SentinelRuleConfig {
@PostConstruct
public void initRules() {
// QPS限流:每秒最多100个请求
FlowRule qpsRule = new FlowRule("order-service")
.setCount(100)
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setLimitApp("default")
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP) // 预热模式
.setWarmUpPeriodSec(10); // 预热时长10秒
// 线程数限流:最多50个并发线程
FlowRule threadRule = new FlowRule("order-service")
.setCount(50)
.setGrade(RuleConstant.FLOW_GRADE_THREAD)
.setLimitApp("default");
List<FlowRule> rules = Arrays.asList(qpsRule, threadRule);
FlowRuleManager.loadRules(rules);
}
}
预热模式(Warm Up)适合冷启动场景——服务刚上线或长时间空闲后,缓存和JIT编译尚未生效,直接承受满载流量会导致大量超时。预热模式在初始阶段只允许少量请求通过,逐步放开到设定的QPS阈值。
熔断降级策略详解
Sentinel提供三种熔断策略:慢调用比例、异常比例和异常数。熔断器状态机包含关闭→打开→半开三个状态,半开状态下允许少量请求探测下游是否恢复。
熔断规则配置:
@PostConstruct
public void initDegradeRules() {
// 慢调用比例熔断
DegradeRule slowCallRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(500) // 慢调用阈值:500ms
.setSlowRatioThreshold(0.6) // 慢调用比例:60%
.setTimeWindow(30) // 熔断持续时间:30秒
.setMinRequestAmount(5) // 最小请求数:5
.setStatIntervalMs(10000); // 统计时间窗口:10秒
// 异常比例熔断
DegradeRule errorRatioRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.5) // 异常比例:50%
.setTimeWindow(30)
.setMinRequestAmount(5)
.setStatIntervalMs(10000);
DegradeRuleManager.loadRules(Arrays.asList(slowCallRule, errorRatioRule));
}
minRequestAmount是一个容易被忽视但非常关键的参数。它决定了熔断判断所需的最小样本量——如果10秒内只有2个请求且都超时,60%的慢调用比例也不应触发熔断,因为样本量不够。默认值为5,高QPS服务可以适当调大。
注解方式接入与降级处理
Sentinel通过@SentinelResource注解声明式地接入限流熔断,无需侵入业务代码:
@Service
public class OrderService {
@SentinelResource(
value = "create-order",
blockHandler = "createOrderBlockHandler",
fallback = "createOrderFallback"
)
public OrderResult createOrder(OrderRequest request) {
// 正常业务逻辑
return orderClient.submit(request);
}
// 限流处理:BlockException
public OrderResult createOrderBlockHandler(OrderRequest request, BlockException ex) {
log.warn("create-order被限流: {}", ex.getRule());
return OrderResult.fail("系统繁忙,请稍后重试");
}
// 熔断降级处理:业务异常
public OrderResult createOrderFallback(OrderRequest request, Throwable throwable) {
log.error("create-order降级: {}", throwable.getMessage());
return OrderResult.fail("服务暂时不可用,已降级处理");
}
}
blockHandler处理限流触发(BlockException),fallback处理业务异常和熔断降级。两者可以同时配置,职责分离清晰。
生产环境中规则持久化是必选项。Sentinel默认将规则存储在内存中,应用重启即丢失。推荐使用Nacos或Apollo作为规则存储中心,Sentinel通过动态数据源监听配置变更,实时加载新规则。高并发设计下,Sentinel集群限流模式通过Token Server统一分配令牌,确保全局限流精度——单机限流100 QPS × 10实例 ≠ 全局1000 QPS,因为请求分布不均匀。集群限流解决了这个问题,但Token Server自身的可用性需要保障,建议部署2个以上Token Server实例,配置主备切换。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot-wei-fu-wu-xian-liu-yu-rong-duan-sentinel-ji/