微服务核心04:熔断限流

把限流、熔断、隔离和降级放到同一条调用链里看,理解系统在过载和下游故障时如何快速止损。

字数 1862 阅读时长 ≈ 6 分钟 2026-6-2 2026-7-12
微服务核心04:熔断限流

熔断限流解决什么问题

熔断限流的底层判断很朴素:系统资源是有限的,不能让所有请求都无条件进入核心链路。请求太多时要限流,下游持续失败时要熔断,局部资源紧张时要隔离,非核心能力不可用时要降级。

它们不是为了”让接口看起来更高级”,而是为了在压力和故障出现时保住系统的基本盘。

更准确地说,这四个控制点解决的是不同问题:

机制解决的问题核心思路
限流流量太多不让过多请求进入系统
熔断下游持续失败不要继续调用明显不健康的下游
隔离局部资源拖垮全局不让一个资源池拖垮所有链路
降级非核心能力不可用时保核心能力不完整时仍然保住核心业务结果

场景:支付通道超时引发雪崩

订单服务调用支付服务,支付服务再调用第三方支付通道。平时一次支付确认 200ms,某天第三方通道开始超时,支付服务响应变成 5s。

如果订单服务没有超时、没有隔离、还配置了多次重试,就会发生连锁反应:

  1. 订单服务线程被支付调用占住
  2. 新的下单请求继续进来并排队
  3. 排队请求越来越多,连接池和线程池被打满
  4. 用户看到的是”整个下单不可用”,而不是”支付通道慢”

熔断限流要解决的就是这种扩散:下游已经不健康时,调用方不要继续把自己拖死。

限流算法怎么选

限流算法要看流量形态。没有哪个算法永远最好,要看场景。

算法原理优点缺点适用场景
固定窗口按时间窗口计数实现简单窗口边界可能出现瞬时两倍流量粗略限流、内部接口
滑动窗口细粒度分片滑动统计更平滑准确统计成本更高精确限流、入口网关
令牌桶匀速生成令牌,请求取令牌允许一定突发,保护入口需要维护令牌状态入口流量、API 网关
漏桶请求匀速流出削峰填谷,输出稳定无法应对突发流量消息处理、后台任务

项目里不需要一上来追求最复杂的算法,先问清楚要保护的是入口 QPS、接口并发,还是下游资源容量。

熔断器状态机

熔断更像一个状态机:

熔断器状态流转

熔断器有三种状态:

  • 关闭(Closed):正常状态,请求正常通过,统计失败率
  • 打开(Open):失败率超过阈值,快速失败,不再调用下游
  • 半开(Half-Open):休眠一段时间后,放行少量请求探测下游是否恢复

状态机的关键是统计窗口和恢复策略。窗口太短会被偶发抖动误伤,窗口太长又会让故障扩散太久;半开探测放量太多,会把刚恢复的下游再次打趴。

一个简化的调用策略可以这样表达:

payment:
  call:
    timeoutMs: 800
    maxConcurrent: 40
    retry: 0
    circuitBreaker:
      errorRate: 50
      windowSeconds: 30
      sleepSeconds: 10
    fallback: async-confirm

这不是某个框架的标准格式,而是设计思路:先限制等待时间和并发,再根据失败比例熔断,最后选择业务能接受的兜底方案。

隔离的多种形式

隔离不只是线程池。它可以是很多种形式,只要能阻止局部故障抢占全局资源,它就在发挥作用。

隔离方式说明适用场景
线程池隔离不同链路用不同线程池CPU 密集、下游调用
连接池隔离不同服务用不同连接池数据库、HTTP 连接
队列隔离不同任务用不同队列异步任务、消息处理
租户隔离不同租户资源独立多租户系统
机房隔离不同机房独立部署高可用部署

常见误区

误区一:限流只做在网关就够了

入口限流很重要,但内部服务也需要保护。比如某个内部任务突然批量调用订单服务,流量不经过外部网关,订单服务自己也要有并发和 QPS 保护。

误区二:熔断就是下游挂了才打开

熔断关注的是失败率、慢调用比例和资源占用,不一定要等到完全不可用。很多时候下游还活着,但已经慢到足以拖垮调用方,这时就应该快速止损。

误区三:重试能提高成功率,所以多配几次

重试只适合短暂网络抖动。下游容量不足时,重试会放大压力。写接口还要考虑幂等,否则一次用户请求可能变成多次扣库存、多次扣款、多条消息。

项目实践:按链路重要性定策略

不要所有接口一刀切,要按链路重要性来定策略。

核心链路,比如下单、支付、登录,要有明确的超时、并发上限、熔断阈值和告警。非核心链路,比如推荐、积分展示、活动浮层,可以更积极地降级。

落地时先做三件事:

  1. 划分核心和非核心接口
  2. 给每个远程调用设置超时和最大并发
  3. 给关键下游定义失败后的业务动作

技术配置只是表面,真正难的是业务兜底。比如库存服务不可用时,下单能不能先接收?支付确认失败时能不能异步补偿?用户看到什么文案?运营是否能接受?这些都要提前设计。

容量估算不要拍脑袋。比如下游支付服务稳定承载 800 QPS,订单服务有 8 个实例,理论上每个实例给支付的并发和 QPS 都要有上限,不能让单个实例在异常时无限制重试。粗略估算可以从这几个量开始:下游容量、调用耗时 P95、实例数、连接池大小、业务峰值系数。限流阈值不是越大越好,而是要小于下游真实承载能力。

排查路径:看哪些指标

熔断限流相关问题,最容易从”接口报错”误判成”服务挂了”。排查时先看:

  • 是否触发限流,触发维度是用户、IP、接口还是应用
  • 熔断器当前状态是关闭、打开还是半开
  • 慢调用比例是否先于错误率上升
  • 线程池、连接池、队列是否接近水位
  • fallback 是否执行成功,是否又压垮了另一个资源
  • 重试次数是否导致下游请求量被放大

尤其要注意:fallback 也可能失败。降级逻辑如果还要远程调用另一个服务,那只是把故障从一条链路挪到另一条链路。

如果看到熔断频繁打开又恢复,通常要检查两件事:阈值是否太敏感,以及半开探测是否太激进。如果看到限流触发但系统仍然很慢,要检查限流是不是只挡住了入口 QPS,却没有限制内部并发和队列长度。