spring cloud sentinel 的 systemrule 默认不生效,因需显式启用系统保护、初始化指标采集器、调用 systemrulemanager.loadrules() 加载规则,且控制台配置重启后丢失,须结合持久化与合理阈值设定。

Spring Cloud Sentinel 支持基于系统级指标(如 CPU 使用率、平均负载、内存占用)的熔断,但默认不开启,且规则加载时机和阈值设定容易误配——直接在控制台填个 CPU 阈值不会生效,必须显式启用系统保护并配置 SystemRule。
为什么 SystemRule 不生效?常见配置遗漏点
系统保护规则(SystemRule)是独立于流控、降级规则的第五类规则,需手动加载,且依赖 Sentinel 的系统指标采集模块。若只配了 FlowRule 或 DegradeRule,SystemRule 完全不会触发。
- 未引入
sentinel-annotation-aspectj或未启用 AOP,导致系统指标采集器未初始化 -
spring.cloud.sentinel.eager未设为true,Sentinel 初始化延迟,SystemRuleManager.loadRules()调用过早,规则被丢弃 - 未调用
SystemRuleManager.loadRules(),仅靠控制台配置在应用重启后丢失(无持久化时) - 系统指标采集默认每 10 秒上报一次,但规则判断窗口是实时滑动的——若 CPU 短暂冲高 2 秒,不足以触发熔断,需结合
highestSystemLoad和avgRt协同判断
如何正确加载 SystemRule(代码方式)
推荐在 @PostConstruct 中加载,且确保 SystemRuleManager 已就绪。注意:系统规则是全局生效的,不能按资源名区分,所有入口共享同一套阈值。
- 设置 JVM 启动参数启用系统指标采集:
-Dcsp.sentinel.app.type=1(标识为服务端应用) - 在配置类中加载规则,例如限制 CPU 使用率超过 75% 时自动拒绝新请求:
List<systemrule> rules = new ArrayList(); SystemRule rule = new SystemRule() .setHighestSystemLoad(7.5) // 平均负载阈值(Linux 下 /proc/loadavg 第一个值) .setAvgRt(45) // 所有入口平均响应时间 ms .setMaxThread(100) // 当前活跃线程数上限 .setQps(1000) // 全局 QPS 上限(可选) .setHighestCpuUsage(0.75); // CPU 使用率,0.0 ~ 1.0 SystemRuleManager.loadRules(rules);</systemrule> - 注意
setHighestCpuUsage(0.75)是小数形式,不是百分比字符串;setHighestSystemLoad对应的是 1 分钟平均负载,非瞬时值
控制台配置 SystemRule 的实际限制
Sentinel Dashboard 支持在「系统规则」页添加 SystemRule,但仅对当前节点有效,且重启客户端后规则丢失——这在多实例部署中极易造成保护不一致。
- Dashboard 页面路径:
http://localhost:8858/#/system(账号密码均为sentinel) - 填写的
Highest System Load字段实际映射到setHighestSystemLoad(),填7.5即可,不要加单位 - 如果看到「系统规则为空」或「未检测到系统指标」,检查日志是否有
Failed to fetch system metrics,大概率是未启用sentinel-metrics-exporter-prometheus或权限不足读取/proc - 生产环境强烈建议关闭控制台动态配置,改用 Nacos 持久化
SystemRule,避免人为误操作导致全站熔断
与 DegradeRule 的关键区别:触发逻辑不同
SystemRule 是被动防御,基于系统整体健康度做全局开关;DegradeRule 是主动干预,针对单个资源(如 userService::query)按异常比例/RT 触发。二者可共存,但优先级上 SystemRule 更底层——即使某个接口的 DegradeRule 未触发,只要 CPU > 0.8,所有请求都会被 SystemRule 拦截。
-
SystemRule判定周期固定为 1 秒,不支持自定义时间窗口 -
DegradeRule的timeWindow可设为 10~60 秒,适合应对短时抖动;SystemRule更适合应对持续性过载 - 当
SystemRule生效时,被拦截请求抛出的是SystemBlockException,不是DegradeException,下游 fallback 逻辑需单独适配
真正起作用的系统熔断,从来不是配完就完事——它依赖稳定的指标采集、合理的阈值阶梯(比如 CPU 从 0.7 → 0.8 → 0.85 分三级降级),以及和容量规划的联动。漏掉 SystemRuleManager.loadRules() 或把 highestCpuUsage 写成 "75%",都会让整套机制静默失效。










