以下内容为Sentinel 的系统保护规则(SystemRule)实现,它用于从全局系统维度对服务进行自我保护,防止因突发流量或资源耗尽导致系统雪崩。
下面我将结构化、深入浅出地解释其设计思想、核心机制和使用方式。
🧠 一、SystemRule 是什么?
SystemRule(系统规则)不针对某个具体接口,而是监控整个应用的全局状态,当系统整体负载过高时,自动拒绝部分请求,保护系统不崩溃。
✅ 它监控 5 个关键指标:
| 指标 | 含义 | 单位 | 默认值(-1 表示关闭) |
|---|---|---|---|
highestSystemLoad | 系统平均负载(Linux load average) | double | -1(关闭) |
highestCpuUsage | CPU 使用率 | [0, 1] | -1(关闭) |
qps | 全局总 QPS(所有入口流量之和) | double | -1(关闭) |
avgRt | 全局平均响应时间 | 毫秒 | -1(关闭) |
maxThread | 全局最大并发线程数 | long | -1(关闭) |
⚠️ 注意:只对
EntryType.IN(入口流量)生效,出口调用(如 Feign、Dubbo 调用下游)不受限。
🔍 二、核心类解析
1.SystemRule:规则定义类
- 继承
AbstractRule - 包含上述 5 个阈值字段
- setter 方法中,≤ 0 的值表示“清除该阈值”
- 支持动态更新(通过
SentinelProperty)
2.SystemRuleManager:规则管理器 + 执行引擎
- 静态单例,全局唯一
- 提供
loadRules()加载规则 - 提供
checkSystem()方法,在每次请求进入时被调用(由 Sentinel Slot Chain 触发) - 内部维护 5 个
volatile阈值变量,支持多线程安全读取 - 启动一个每秒执行一次的定时任务(
SystemStatusListener),采集系统指标
3.SystemStatusListener:系统指标采集器
- 实现
Runnable,由ScheduledExecutorService每秒调度 - 通过JMX(Java Management Extensions)获取:
OperatingSystemMXBean.getSystemLoadAverage()→ 系统负载OperatingSystemMXBean.getSystemCpuLoad()→ 系统 CPU 使用率getProcessCpuTime()+uptime→ 进程 CPU 使用率(更适用于容器环境)
- 将最新指标存入
volatile字段,供checkSystem()读取
⚙️ 三、checkSystem():核心拦截逻辑
publicstaticvoidcheckSystem(ResourceWrapperresource,intcount)throwsBlockException{// 1. 只检查入口流量if(resource.getEntryType()!=EntryType.IN)return;// 2. 检查 QPSif(Constants.ENTRY_NODE.passQps()+count>qps)thrownewSystemBlockException("qps");// 3. 检查线程数if(Constants.ENTRY_NODE.curThreadNum()>maxThread)thrownewSystemBlockException("thread");// 4. 检查平均 RTif(Constants.ENTRY_NODE.avgRt()>maxRt)thrownewSystemBlockException("rt");// 5. 检查系统负载(带 BBR 优化)if(load>threshold&&!checkBbr(currentThread))thrownewSystemBlockException("load");// 6. 检查 CPU 使用率if(cpuUsage>threshold)thrownewSystemBlockException("cpu");}💡
Constants.ENTRY_NODE是 Sentinel 的根节点,统计所有入口流量的聚合指标。
🧩 四、关键机制详解
✅ 1.系统负载(Load)与 BBR 算法
Sentinel 借鉴了TCP BBR(Bottleneck Bandwidth and RTT)的思想:
当系统负载高时,不一定立刻熔断,而是判断当前是否处于“危险区”。
checkBbr()逻辑:
privatestaticbooleancheckBbr(intcurrentThread){// 计算理论最大并发 = 最大成功QPS × 最小RT / 1000longtheoreticalMaxConcurrency=maxSuccessQps*minRt/1000;// 如果当前线程数 > 理论最大并发,说明已过载 → 拒绝return!(currentThread>1&¤tThread>theoreticalMaxConcurrency);}📌意义:避免在“管道刚满”时误判为过载。只有当排队严重(线程数远超容量)时才熔断。
✅ 2.CPU 使用率的双重采集
doublesystemCpuUsage=osBean.getSystemCpuLoad();// 整机 CPUdoubleprocessCpuUsage=...;// 当前 JVM 进程 CPUcurrentCpuUsage=Math.max(processCpuUsage,systemCpuUsage);🎯为什么取 max?
- 在物理机上,
systemCpuLoad更准- 在Docker/K8s 容器中,
systemCpuLoad可能不准(看到的是宿主机负载),而processCpuTime更可靠- 取 max 保证最坏情况被捕捉
✅ 3.多规则合并策略
当你配置多个SystemRule时:
loadSystemConf(rule){highestSystemLoad=Math.min(highestSystemLoad,rule.getHighestSystemLoad());qps=Math.min(qps,rule.getQps());// ...}📌取最严格的阈值(最小值)
例如:规则 A 设 QPS=100,规则 B 设 QPS=80 → 实际生效的是80
🛠️ 五、如何使用?
示例:限制全局 QPS ≤ 100,线程数 ≤ 10,RT ≤ 50ms
List<SystemRule>rules=newArrayList<>();SystemRulerule=newSystemRule();rule.setQps(100);// 全局 QPS ≤ 100rule.setMaxThread(10);// 并发线程 ≤ 10rule.setAvgRt(50);// 平均 RT ≤ 50msSystemRuleManager.loadRules(Collections.singletonList(rule));高级用法:结合 CPU 和 Load(仅 Linux)
SystemRulerule=newSystemRule();rule.setHighestSystemLoad(5.0);// load average ≤ 5rule.setHighestCpuUsage(0.8);// CPU ≤ 80%SystemRuleManager.loadRules(...);⚠️ 注意:
highestSystemLoad在 Windows 上无效(返回 -1)
📊 六、监控与日志
当系统负载超过阈值时,SystemStatusListener会打印详细日志:
[INFO] Load exceeds the threshold: load:6.2341; cpuUsage:0.8721; qps:120.5; rt:65.3; thread:15; success:110.2; minRt:20.0; maxSuccess:115.0帮助你快速定位是CPU、线程、RT 还是 QPS导致的问题。
🧪 七、性能测试建议
官方注释提到:
“To set the threshold appropriately, performance test may be needed.”
✅ 建议步骤:
- 压测系统,找到最大稳定 QPS(maxSuccessQps)
- 记录此时的平均 RT、线程数、CPU、Load
- 将阈值设为稳定值的 70%~80%,留出安全余量
❓常见问题
Q:为什么设置了 QPS=100,但实际通过了 105?
A:Sentinel 注释中提到:
real passed QPS = QPS set + concurrent thread number
因为QPS 统计有延迟,且允许少量突发(类似令牌桶),这是正常现象。
Q:SystemRule 和 DegradeRule 有什么区别?
| 对比项 | SystemRule | DegradeRule |
|---|---|---|
| 作用范围 | 全局(整个应用) | 单个资源(如 /order) |
| 触发条件 | 系统级指标(CPU/Load/QPS) | 资源级指标(RT/异常) |
| 目的 | 防系统雪崩 | 防慢调用/异常扩散 |
✅ 两者互补:SystemRule 保命,DegradeRule 精细化治理。
✅ 总结
Sentinel 的 SystemRule 是一个“系统级熔断器”,它:
- 🛡️从全局视角保护应用,防止资源耗尽
- 📈实时采集CPU、Load、QPS、RT、线程 5 大指标
- 🧠引入 BBR 思想,避免误判
- 🐳兼容容器环境,精准获取进程 CPU
- ⚙️支持动态配置,无需重启
💡最佳实践:在生产环境中,务必配置 SystemRule作为最后一道防线,配合 DegradeRule 和 FlowRule,构建完整的稳定性体系。
理解这些,你就掌握了 Sentinel最高层级的自我保护能力。