用 sentinel.entry 包裹调用,配合 errorratio 或 slowrequestratio 熔断策略,再加 blockhandler 和 fallback 分离限流与熔断响应——这是 go 微服务防雪崩最稳的组合。

直接结论:用 sentinel.Entry 包裹调用,配合 ErrorRatio 或 SlowRequestRatio 熔断策略,再加 blockHandler 和 fallback 分离限流与熔断响应——这是 Go 微服务防雪崩最稳的组合。
为什么不能只靠超时或重试?
超时只能防止单次阻塞,但 goroutine 仍会堆积;重试在下游已不可用时反而加剧压力。雪崩本质是资源耗尽(连接池、goroutine、线程)+ 故障扩散,必须从“请求准入”和“调用链隔离”两个层面切断。
常见错误现象:panic: runtime: out of memory、http: Accept error: accept tcp: too many open files、大量 context.DeadlineExceeded 但下游服务其实早挂了。
- 超时只是“等多久”,不解决“要不要等”
- 重试没配退避策略,会把 1 次失败放大成 3–5 次冲击
- 没做资源粒度隔离,一个慢查询拖垮整个 HTTP handler
怎么配 sentinel.Entry 才不白配?
资源名必须按业务语义定义,不是随便起个 "api" 就完事。每个远程调用点(如 DB 查询、RPC 接口、HTTP client)都该有独立资源名,否则统计失真、规则失效。
正确示例:sentinel.Entry("user-service:query-by-id")、sentinel.Entry("payment-gateway:submit-order");错误示例:sentinel.Entry("api")、sentinel.Entry("http-call")。
- 资源名一旦上线就不能改,改名等于新建资源,旧监控断层、规则不生效
-
Entry必须紧跟实际调用前,且调用后立刻检查err != nil——nil才代表放行 - 别在 handler 外层统一包一层
Entry,那只是给整个接口限流,不是保护下游依赖
ErrorRatio 和 SlowRequestRatio 怎么选?
内部服务间 RPC 调用波动小、错误类型明确(如 gRPC status code),优先用 ErrorRatio;对外部 HTTP API、数据库驱动等延迟抖动大的场景,SlowRequestRatio 更靠谱。
典型误配:DB.Query 用 ErrorRatio → 网络瞬断导致短暂超时,但没报错,错误率不达标,熔断器不触发,连接池持续被占满;third-party-sms-api 用 SlowRequestRatio 阈值设 800ms → 实际 P95 是 1.2s,结果频繁误熔。
- 内部 RPC:
Strategy: circuitbreaker.ErrorRatio,Threshold: 0.5,MinRequestAmount: 5 - 外部 HTTP/DB:
Strategy: circuitbreaker.SlowRequestRatio,MaxAllowedRtMs: 1200,Threshold: 0.3 - 无论哪种,
StatIntervalMs别设太短(如 1000ms),滑动窗口至少 10s 才能平滑噪声
blockHandler 和 fallback 容易混用的坑
blockHandler 是限流被拒时的兜底,fallback 是熔断触发后的降级——两者触发条件不同,返回结构必须一致,否则前端解析失败。
常见错误:fallback 函数里又调一次 sentinel.Entry("cache-get") → 可能嵌套熔断;blockHandler 直接返回 "too many requests" 字符串,而正常接口返回的是 JSON 对象。
-
blockHandler应返回缓存数据、默认值或空数组,字段结构与主逻辑完全一致 -
fallback不要再发新网络请求,优先用预热好的内存数据(如sync.Map存的兜底商品列表) - 所有降级路径必须走单元测试,验证字段缺失、类型错位、空指针等边界情况
真正难的不是配参数,而是把“哪个调用点该用什么策略”想清楚——资源名定义错了,后面所有规则、监控、告警全偏移;fallback 里再调外部服务,等于在防火墙里又开了扇窗。











