在分布式系统中,突发流量、热点参数、慢接口等都可能导致系统不可用。Sentinel 是阿里巴巴开源的服务稳定性组件,提供流量控制、熔断降级、系统自适应、热点参数限流等能力,并配套控制台用于规则下发与可视化运维。
本文按“通俗类比 → 原理流程 → 源码关键点 → 实战配置 → 最佳实践与常见坑”来讲解,帮助你既能读源码也能马上上线实战。
一、先用生活类比把问题想清楚
想象一个餐厅高峰期:
- 限流:门口管控进客速度,超额的不进来排队或被拒绝。
- 降级:高峰时先停售耗时菜品,只做快餐。
- 系统保护:厨房整体负载太高时暂缓接单。
- 热点限流:招牌菜某人一次不能买太多。
- 可视化运维:店长看着监控台实时调整限流策略。
Sentinel 就是为“服务厨房”做这些策略的组件。
二、核心概念一览(通俗版)
- Resource(资源):要保护的对象,通常是接口、方法或 URL。
- Entry / SphU:请求入口,每次访问都通过
SphU.entry(resource)
申请进入权限。 - Context(上下文):区分调用来源(origin),便于对不同来源下发不同策略。
- Rule(规则):FlowRule、DegradeRule、ParamFlowRule、SystemRule、AuthorityRule 等。
- Slot 链:内部使用责任链(Slot)逐项处理校验与统计(FlowSlot、DegradeSlot、StatSlot 等)。
- BlockException:被限流或降级时抛出的异常,应用可捕获并降级处理。
- Dashboard:可视化控制台,支持规则下发与在线调参。
三、整体处理流程(简化图)
说明:应用在关键点调用 SphU.entry(resource)
,经过规则检查通过则执行业务,不通过就抛 BlockException
,通常在应用层进行兜底或提示。
四、注解保护与 blockHandler 流程(图示)
实战:在 Spring Boot 中可用 @SentinelResource
标注方法并指定 blockHandler
,发生限流时自动调用该处理器返回降级结果。
五、热点参数限流(ParamFlow)思路
要点:ParamFlow 对每个参数值单独统计(比如 userId、itemId),当某个参数的访问速率超过阈值,仅对该参数值生效,而不影响其他参数值。
六、Slot 链(责任链)设计(简化)
说明:Sentinel 内部把逻辑拆成很多小槽(Slot),按顺序执行检查与统计,便于扩展与维护。
七、Dashboard 与规则下发流程
实战:生产环境通常在 Dashboard 线上调整规则,客户端会接收并立即生效;也可以在应用启动时用代码或配置加载规则。
八、关键源码与常用 API(可直接上手)
1) 入口示例(最常见)
try (Entry entry = SphU.entry("getUser")) {
// 业务逻辑
} catch (BlockException ex) {
// 限流或降级处理
}
也可用注解(Spring):
@SentinelResource(value = "getUser", blockHandler = "handleBlock")
public User getUser(Long id) { ... }
public User handleBlock(Long id, BlockException ex) { return fallback; }
2) 动态下发流控规则(代码)
FlowRule rule = new FlowRule();
rule.setResource("getUser");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按 QPS 限流
rule.setCount(10); // 阈值 10 QPS
FlowRuleManager.loadRules(Collections.singletonList(rule));
3) 热点参数限流(代码)
ParamFlowRule pRule = new ParamFlowRule("getUser")
.setParamIdx(0) // 作用于第 1 个参数
.setCount(5); // 单个参数允许 5 QPS
ParamFlowRuleManager.loadRules(Collections.singletonList(pRule));
4) 熔断降级(慢调用 RT)
DegradeRule dr = new DegradeRule("getUser")
.setGrade(RuleConstant.DEGRADE_GRADE_RT) // RT 策略
.setCount(100) // RT 阈值 ms
.setTimeWindow(10); // 熔断时间窗口 秒
DegradeRuleManager.loadRules(Collections.singletonList(dr));
5) 关键管理类(便于阅读源码)
SphU
:静态入口。ContextUtil
:上下文管理。FlowRuleManager
、DegradeRuleManager
、ParamFlowRuleManager
:规则管理器。SlotChain
与Slot
实现:责任链执行逻辑。BlockException
:被限流/降级时抛出。
九、流控算法与熔断策略(要点速记)
- 流控(Flow)
- 支持 QPS、并发数、预热等多模式。
- 统计使用滑动窗口或令牌思路,结合预热策略平滑流量。
- 熔断(Degrade)
- 支持慢调用 RT、异常比率、异常数三种触发器。
- 熔断期间直接拒绝或使用兜底逻辑,窗口结束后尝试放行探测。
- 热点参数(ParamFlow)
- 针对参数值单独统计,支持阈值、链路来源区分、控制冷却等策略。
十、实践技巧与常见坑
常见坑
- 不区分 origin(来源):没设置
ContextUtil.enter(context, origin)
会让规则无法区分来源(前端、其他服务、管理控制台)。 - ParamFlow 下标错误:
setParamIdx
下标写错会导致规则无效。 - 熔断阈值单位误解:RT 是毫秒,别把秒当毫秒。
- 没有兜底逻辑:BlockException 未处理,会把异常暴露给上游。
- 规则未持久化或未下发:忘记在 Dashboard 下发或启动时加载规则。
最佳实践
- 资源粒度:把 resource 定义为业务维度(service:method 或 URL+method)。
- 区分来源:对内外流量设置不同 origin,使用 Context 区分。
- 优先热点限流:先保护热点参数,避免全局降级影响面太广。
- 熔断+兜底:熔断后必须有 fallback(缓存、默认值、友好提示)。
- 灰度下发规则:先在灰度环境验证规则再在线上下发。
- 监控联动:和 Prometheus/日志一起做告警,及时干预。
十一、结语(一句话)
Sentinel 是一套“可下发规则 + 高性能埋点与统计”的服务稳定性方案,能在运行时智能保护你的服务,避免雪崩与级联故障。