服务熔断与限流:Sentinel 落地实录

微服务架构里最怕的不是某个服务挂,是一个服务挂了把整个调用链拖死(雪崩)。我们在 Go 微服务里落地 Sentinel(限流 + 熔断 + 降级三件套),这篇文章是完整记录:配置、阈值、演练。

一、三个概念先分清

作用 例子
限流 防"请求太多" 某接口每秒最多 1000 次
熔断 防"下游已挂还死等" 简历服务错误率 > 50% → 快速失败 30s
降级 挂了给"次优响应" 推荐服务挂了 → 返回默认热门列表

核心思想:把"不可控的故障"变成"可控的拒绝"——宁可返回降级数据,不可无限等待拖死上游。

二、限流:三挡阈值设计

我们按资源 + 场景分挡:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Sentinel 规则示例(Go)
_, err := sentinel.Entry("delivery:submit",
    sentinel.WithTrafficType(base.Inbound),
)
if err != nil {
    return 429   // 限流:快速失败
}
defer entry.Exit()

// 规则:QPS 限流,突发 2 倍
rules := []*flow.Rule{
    {
        Resource:        "delivery:submit",
        TokenCalculate:  flow.Direct,
        Threshold:       1000,   // 每秒 1000
        Burst:           2000,   // 突发 2 倍
    },
}

阈值怎么定(不是拍脑袋):

阈 例 值 : D = B 下 连 游 接 容 池 量 2 × 0 0 安 , 全 单 系 连 数 接 能 扛 5 Q P S → 上 游 限 8 0 0 Q P S ( 留 2 0 % 余 量 )

原则:限流阈值跟着最弱下游走。你的服务限流限的是"别把下游打爆",不是"别把自己打爆"。

三、熔断:错误率 + 慢调用双维度

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 熔断规则:错误率
rules := []*circuitbreak.Rule{
    {
        Resource:         "resume:search",
        Strategy:         circuitbreak.ErrorRatio,
        RetryTimeoutMs:   30000,      // 熔断 30s 后试探
        MinRequestAmount: 20,         // 最少请求数(防抖动误熔断)
        Threshold:        0.5,        // 错误率 > 50% 熔断
    },
    // 慢调用熔断:P99 > 2s
    {
        Resource:         "resume:search",
        Strategy:         circuitbreak.SlowRequestRatio,
        MaxAllowedRtMs:   2000,
        Threshold:        0.3,        // 30% 请求超 2s 就熔断
    },
}

参数含义(都重要):

  • MinRequestAmount=20:样本太少不熔断,防抖动(2 个请求失败不算故障)
  • RetryTimeoutMs=30000:熔断后 30s 半开试探,成功恢复、失败再断
  • 错误率 50% 是保守值:宁可误断,不可扩散

四、降级:兜底响应

1
2
3
4
5
// 推荐服务熔断时:返回兜底数据
if err := sentinel.Entry("recommend:list"); err != nil {
    // 熔断/限流触发 → 降级
    return defaultHotList()   // 默认热门职位,接口正常返回
}

降级数据三原则:

  1. 有数据:降级也要返回"可用但次优"的数据(热门榜、缓存快照),别返回空
  2. 有标记:降级响应带 is_degraded: true,前端可提示"推荐暂不可用"
  3. 有兜底:降级数据本身要可靠(静态配置或本地缓存,不能再依赖已挂的下游)

五、全链路配合

网 业 下 关 务 游 限 │ ▼ 服 │ ▼ ( 流 务 D ( 限 B 入 流 / 口 E 总 + S 闸 / ) 熔 R 断 P C + ) 降 级

关键链路设计:

用 户 请 求 → 服 务 A ├ ├ └ ─ ─ ─ 正 B B 常 熔 降 → 断 级 调 → → 服 务 快 返 B 速 回 失 兜 败 底 ( 数 不 据 等 待 )

超时是熔断的前提:没有超时,请求永远挂着,熔断统计(错误率)永远凑不齐样本。限流 + 熔断 + 超时三件套必须一起上。

六、阈值怎么调(经验)

1 2 3 4 5 . . . . . 先 限 熔 每 告 观 流 断 发 警 察 : : 版 : 一 基 错 验 熔 周 线 误 证 断 : 率 : 触 压 × 压 发 测 5 测 次 1 0 打 数 + . % 超 5 阈 > 监 ( / 值 控 留 , 0 拿 突 慢 确 到 发 调 认 要 基 余 用 触 告 线 量 发 警 ( ) 3 ( 正 0 + 熔 常 % 断 ( 恢 是 Q 保 复 " P 守 正 S 起 在 、 步 救 P , 你 9 误 " 9 断 的 、 调 信 错 高 号 误 ) , 率 也 ) 是 " 下 游 有 问 题 " 的 信 号 )

七、演练:真把下游关了试试

不演练的熔断配置 = 没配。每季度演练一次:

1
2
3
4
5
6
# 演练步骤
1. 挑一个非核心服务(如推荐服务)
2. 人为停掉(kill pod / 关接口)
3. 观察:上游是否快速失败(不等待)、是否降级(不白屏)
4. 恢复服务,观察熔断半开 → 恢复
5. 记录:熔断生效时间、降级响应率、有无 5xx 泄漏

总结

熔断限流的核心认知:

  1. 限流跟下游容量走,阈值是可计算的,不是拍脑袋
  2. 熔断 = 错误率/慢调用 + 最小样本 + 半开恢复,防的是故障蔓延
  3. 降级要"有数据、有标记、有兜底",宁可次优不可报错
  4. 超时、限流、熔断三件套一起上,缺一不可
  5. 必须演练:不演练 = 上线那天才知道配置对不对

熔断限流是微服务的"安全气囊":平时看不见,撞车时保命。气囊不好使比没有气囊更可怕。