Sentinel系统规则必须设resourceName="default",因系统指标(CPU/Load/RT)是全局维度的;埋点需用sentinel.WithTrafficType(base.Inbound),且Entry须在主goroutine调用并判空defer Exit。

单靠固定 QPS 限流扛不住突发流量,Gin 本身不提供自适应能力,必须靠 Sentinel 的系统规则(如 CPU、Load、RT)动态响应,否则容易在高峰时误杀或放行过多。
为什么 sentinel.SystemRule 必须设 resourceName = "default"
系统级指标(CPU、Load、RT、并发数)不是针对某个接口的,而是全局入口维度的统计。Sentinel Go 要求所有系统规则的 resourceName 统一为 "default",否则规则加载成功但完全不触发。埋点时也必须传 sentinel.WithTrafficType(base.Inbound),否则指标不会归入系统维度。
-
sentinel.Entry("GET:/api/order", sentinel.WithTrafficType(base.Inbound))→ 用于接口级流控,resourceName可以是任意字符串 -
sentinel.Entry("default", sentinel.WithTrafficType(base.Inbound))→ 唯一合法的系统规则埋点写法 - 如果混用(比如用
"system"或"global"),规则加载无报错,但system.LoadRules()后永远不生效
sentinel.Entry() 必须在主 goroutine 调用且 e.Exit() 必须判空 defer
Entry 返回的 e 可能为 nil(比如规则未初始化完成、配置加载失败、或 Sentinel 初始化被跳过),直接 defer e.Exit() 会 panic。同时,Entry 不能丢进 go func() 里调用——统计上下文绑定的是当前 goroutine,跨协程会导致指标丢失、流控失效。
- 正确写法:
e := sentinel.Entry("default", sentinel.WithTrafficType(base.Inbound)); if e != nil { defer e.Exit() } - 错误写法:
go func() { sentinel.Entry(...) }()或defer e.Exit()不判空 - recover() 里补
e.Exit()无效:panic 后 goroutine 已终止,上下文已销毁
系统规则选型:Load、CPU、RT 三者怎么选
同一时间只生效最先满足的规则,优先级由加载顺序决定,但更关键的是指标稳定性。生产环境最推荐 system.Load,其次是 system.CPU,慎用 system.RT。
-
system.Load:Linux 系统平均负载(1 分钟),对突发 CPU/IO 敏感,且天然带滞后性,不易抖动误触发;TriggerCount设 8.0 对应 8 核机器较稳妥 -
system.CPU:需注意采样间隔(默认 1s),若服务本身 CPU 波动大(如 GC 尖峰),可能频繁触发;建议配合StatIntervalInMs: 60000使用 -
system.RT:P90 RT 超过阈值才触发,但SlowRatioThreshold若设太小(如 0.1)、MinRequestAmount太低(如 <20),滑动窗口内请求数不足,错误率抖动剧烈,极易误熔断
自适应不是“全自动”,system.LoadRules() 必须在启动早期一次性加载
规则不能在每次请求里重复调用 system.LoadRules(),它内部加锁且会重置统计器,高频调用会导致规则引擎卡死、指标归零、限流瞬间失效。真正需要动态调整时,应通过外部配置中心(如 Nacos、Consul)监听变更,再在回调中安全 reload。
最容易被忽略的一点:Sentinel Go 的系统规则和资源埋点是解耦的——即使没定义任何 flow.Rule,只要 system.LoadRules() 加载了规则 + 主 goroutine 正确埋点 + resourceName 是 "default",系统保护就会自动生效。别以为没配流控规则就等于没开自适应。


















