熔断器模式与三种状态机
微服务架构中,服务间的同步调用形成复杂的依赖链。当某个下游服务响应变慢或不可用时,上游服务的请求线程被持续占用,最终耗尽线程池导致级联故障。服务降级与熔断器模式通过快速失败和资源隔离机制,防止单点故障扩散到整个系统。本文对比Sentinel和Hystrix两种主流熔断组件的设计差异,给出生产环境的限流降级配置方案。
熔断器的核心是有限状态机,包含Closed(关闭)、Open(打开)、Half-Open(半开)三种状态。Closed状态下请求正常放行,统计失败率。当失败率超过阈值,熔断器切换到Open状态,所有请求直接返回降级响应,不再调用下游服务。经过冷却时间后进入Half-Open状态,放行少量探测请求,探测成功则回到Closed状态,失败则重新回到Open状态。
三种状态的转换参数直接影响保护效果。熔断阈值过低导致频繁误断,过低则失去保护作用。生产环境通常设置失败率阈值50%、最小请求数20、熔断持续10秒、半开探测请求数3。
Sentinel与Hystrix设计对比
Hystrix采用线程池隔离策略,每个下游服务分配独立线程池,服务调用在独立线程执行。隔离性强但线程上下文切换开销大。Hystrix已进入维护模式,Netflix不再积极开发,社区转向Resilience4j和Sentinel。
Sentinel由阿里巴巴开源,采用信号量隔离而非线程池隔离,通过滑动窗口统计QPS和响应时间,性能开销更低。Sentinel的控制台提供实时监控和动态规则推送,运维友好度优于Hystrix。Sentinel的规则类型更丰富,覆盖流控、熔断降级、系统自适应保护和热点参数限流。
| 特性 | Sentinel | Hystrix |
|---|---|---|
| 隔离策略 | 信号量 | 线程池/信号量 |
| 熔断策略 | 慢调用比例/异常比例/异常数 | 异常比例 |
| 实时监控 | Dashboard控制台 | Dashboard/Hystrix Stream |
| 动态规则 | Nacos/Zookeeper/Apollo推送 | Archaius配置 |
| 限流维度 | QPS/并发线程数/热点参数 | 不支持 |
Sentinel流控规则配置实战
Sentinel的Java SDK通过SphU.entry定义资源入口,资源粒度可以是接口级别或方法级别。
@SentinelResource(value = "queryOrder",
blockHandler = "queryOrderBlockHandler",
fallback = "queryOrderFallback")
public OrderDTO queryOrder(String orderId) {
return orderService.findById(orderId);
}
// 限流降级处理
public OrderDTO queryOrderBlockHandler(String orderId, BlockException ex) {
log.warn("订单查询被限流, orderId={}, rule={}", orderId, ex.getRule());
return OrderDTO.builder()
.orderId(orderId)
.status("SYSTEM_BUSY")
.message("系统繁忙,请稍后重试")
.build();
}
// 异常降级处理
public OrderDTO queryOrderFallback(String orderId, Throwable e) {
log.error("订单查询异常, orderId={}", orderId, e);
return OrderDTO.builder()
.orderId(orderId)
.status("SERVICE_UNAVAILABLE")
.cacheData(redisTemplate.getFor(orderId))
.build();
}
blockHandler处理Sentinel规则触发(限流、熔断),fallback处理业务异常。两者职责分离,blockHandler返回快速失败响应,fallback返回兜底数据(如缓存)。
流控规则通过API或Dashboard配置:
// QPS限流规则
FlowRule qpsRule = new FlowRule("queryOrder")
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(100)
.setLimitApp("default")
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
// 并发线程数限流规则
FlowRule threadRule = new FlowRule("queryOrder")
.setGrade(RuleConstant.FLOW_GRADE_THREAD)
.setCount(50)
.setLimitApp("default");
// 排队等待模式(匀速通过)
FlowRule queueRule = new FlowRule("queryOrder")
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(100)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
.setMaxQueueingTimeMs(2000);
FlowRuleManager.loadRules(Arrays.asList(qpsRule, threadRule, queueRule));
QPS限流适合接口级保护,并发线程数限流适合慢调用场景。排队等待模式将突发流量整形为匀速请求,适合消息队列消费者的流控。
Sentinel熔断降级规则配置
Sentinel提供三种熔断策略:慢调用比例、异常比例、异常数。
// 慢调用比例熔断
DegradeRule slowCallRule = new DegradeRule("queryOrder")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(500)
.setSlowRatioThreshold(0.5)
.setMinRequestAmount(20)
.setStatIntervalMs(10000)
.setTimeWindow(10);
// 异常比例熔断
DegradeRule errorRatioRule = new DegradeRule("paymentService")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.5)
.setMinRequestAmount(10)
.setStatIntervalMs(10000)
.setTimeWindow(15);
// 异常数熔断
DegradeRule errorCountRule = new DegradeRule("paymentService")
.setGrade(CircuitBreakerStrategy.ERROR_COUNT.getType())
.setCount(10)
.setMinRequestAmount(10)
.setStatIntervalMs(60000)
.setTimeWindow(30);
DegradeRuleManager.loadRules(Arrays.asList(slowCallRule, errorRatioRule, errorCountRule));
慢调用比例熔断适合对延迟敏感的核心接口,500ms作为慢调用阈值,当超过半数请求超过阈值时熔断。异常比例熔断适合不稳定的外部依赖服务,50%错误率即触发保护。异常数策略适合低QPS但错误集中的场景。
Spring Cloud Alibaba整合Sentinel动态规则
生产环境通过Nacos推送动态规则,避免代码硬编码和重启生效。Spring Cloud Alibaba提供sentinel-datasource-nacos模块实现规则同步。
spring:
cloud:
sentinel:
transport:
dashboard: 10.0.1.20:8858
port: 8719
datasource:
flow:
nacos:
server-addr: 10.0.1.21:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
rule-type: flow
degrade:
nacos:
server-addr: 10.0.1.21:8848
dataId: ${spring.application.name}-degrade-rules
groupId: SENTINEL_GROUP
rule-type: degrade
规则以JSON格式存储在Nacos配置中心,修改后秒级推送到所有应用实例。配合Sentinel Dashboard可视化配置界面,运维人员可以实时调整限流策略而无需代码发布。
[
{
"resource": "queryOrder",
"limitApp": "default",
"grade": 1,
"count": 100,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
系统自适应保护与热点参数限流
Sentinel的系统自适应保护规则根据系统整体负载(CPU、Load、RT、线程数、入口QPS)自动限流,是全局兜底策略,防止系统过载崩溃。
SystemRule systemRule = new SystemRule();
systemRule.setHighestCpuUsage(0.8);
systemRule.setHighestSystemLoad(4.0);
systemRule.setAvgRt(100);
systemRule.setMaxThread(200);
systemRule.setQps(5000);
SystemRuleManager.loadRules(Collections.singletonList(systemRule));
热点参数限流对特定参数值施加独立限流阈值,适用于秒杀场景的爆款商品ID限流:
ParamFlowRule rule = new ParamFlowRule("seckillOrder")
.setParamIdx(0)
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(1000)
.setParamFlowItemList(Arrays.asList(
new ParamFlowItem().setObject("SKU_HOT_001")
.setClassType(String.class.getName())
.setCount(5000)
));
普通商品共享1000 QPS额度,爆款商品SKU_HOT_001单独分配5000 QPS。这种细粒度参数限流避免单个热点参数拖垮全局限流策略。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/wei-fu-wu-jia-gou-fu-wu-jiang-ji-rong-duan-sentinel-yu/