bbr策略不能自动感知系统负载并拒绝服务,仅基于rt和并发数自适应降速;真要实现负载感知+拒绝,需手动集成系统指标采集(如gopsutil)、在首个中间件中早拦截并返回503。

不能靠 system.BBR 策略直接“自动感知负载并拒绝服务”——它只做自适应限流,不拒绝,也不真正感知 CPU/内存等系统指标。
BBR 策略实际行为:降速,不是拒接
system.BBR 是 Sentinel 的一种系统保护策略,它基于响应时间(RT)和并发数估算当前服务水位,动态下调 QPS 阈值。但它不会主动返回 429 或中断请求,而是让超出当前阈值的请求排队或等待,最终可能因超时被客户端放弃。真实效果是“变慢”,而非“明确拒绝”。
- 触发条件是 RT 上升 + 入口并发增长,不是 CPU > 90% 或内存 OOM
- 它不读取
/proc/stat、/sys/fs/cgroup或任何宿主机指标 - 即使机器已卡死,只要 RT 没飙升(比如慢查询全堵在 DB 层),BBR 仍可能放行大量请求
真要“感知负载 + 拒绝服务”,得自己拉系统指标
必须手动集成指标采集(如 gopsutil)+ 自定义中间件,在请求入口判断并 Abort。Sentinel 的 system.Rule 不支持挂钩到 OS 层指标。
- 用
cpu.Percent和mem.VirtualMemory每秒采样一次,缓存最近 5 秒均值 - 在 Gin 中间件里检查:
if cpuAvg > 95 || memUsedPercent > 90 { c.AbortWithStatusJSON(503, gin.H{"msg": "system overloaded"}) } - 避免每次请求都调系统 API,采样频率建议 ≥ 1s,结果存全局变量或 sync.Map
- 注意容器环境:cgroup v2 下需读
/sys/fs/cgroup/memory.current而非mem.VirtualMemory
拒绝时机必须早于业务逻辑执行
系统负载高时,最怕的是请求进来后才开始查 DB、调下游——这会让堆积雪球越滚越大。拒绝动作必须放在第一个中间件,且不能依赖任何外部 IO。
- 注册顺序必须是:
r.Use(SystemLoadGuardMiddleware)→r.Use(AuthMiddleware)→ … - 不要在中间件里调
c.ShouldBindJSON或c.GetHeader前做判断——解析过程本身就有开销 - 拒绝响应头加
Retry-After: 1,方便上游重试调度 - 记录日志但别打全量:只记
cpu: 97.2%, mem: 94.1%,不记请求 body/path
系统级负载拒绝不是配置开关,而是指标采集 + 门限判断 + 早期拦截三者缺一不可。BBR 只解决流量节奏问题,真要保命,得自己动手把“CPU 过载”翻译成 HTTP 503。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











