高并发系统的过载保护
过载保护的目标,不是让系统在任何流量下都毫无损失,而是在资源不足时主动控制损失,保住核心链路,并为恢复争取时间。
现实生活中,保险丝会在电流过大时熔断,水库会在水位超过警戒线时泄洪。软件系统同样需要这样的保护机制:当请求量或资源消耗超过承载能力时,系统必须及时限流、拒绝、降级或隔离,否则局部故障很容易被放大为全链路雪崩。
一、系统过载会带来什么后果
单机过载通常只影响有限用户,但在分布式系统中,一个节点的异常可能沿调用链迅速传播:
- 响应时间持续上升:线程、连接和队列被占满,请求开始排队。
- 重试放大流量:用户刷新、客户端重试和服务间重试叠加,真实流量被成倍放大。
- 故障向外扩散:负载均衡器将请求转移到其他节点,原本健康的节点也可能相继过载。
- 核心链路被拖垮:非核心功能与核心交易争抢同一组资源,最终导致系统整体不可用。
这类现象很像雪崩:最初只是局部平衡被打破,随后在滚雪球效应和多米诺骨牌效应的共同作用下,影响范围越来越大。

图 1:局部失衡可能逐步演变为系统性雪崩
二、系统为什么会过载
系统性能通常不是随着负载增加而线性下降。负载较低时,增加少量请求只会让响应稍慢;一旦越过性能拐点,线程切换、锁竞争、内存回收、磁盘随机 I/O、网络拥塞等开销会相互叠加,吞吐量反而下降,延迟则快速上升。
常见瓶颈主要包括:
- CPU:计算密集、序列化或压缩等操作占用大量计算资源。
- 内存:对象堆积、缓存膨胀或频繁 GC 导致可用内存不足。
- 并发资源:线程池、连接池、文件句柄或协程数量达到上限。
- I/O:数据库、磁盘、网络带宽或下游接口成为瓶颈。
真正危险的往往不是某个资源达到 100%,而是系统进入了请求越多、处理越慢;处理越慢、重试越多的恶性循环。
北京奥运门票销售事件带来的启示
2007 年 10 月 30 日,北京奥运门票第二阶段销售启动。面对短时间内高度集中的购票需求,网站、呼叫中心和银行代售网点承受了远超预期的访问压力,最终整个售票系统过载。
当后端响应变慢后,用户不断刷新页面;刷新产生的新请求又进一步挤占资源。历史运营数据表明,请求量在这一过程中被大幅放大。这个案例说明:过载不仅来自原始流量,也来自超时、刷新和无节制重试形成的流量放大。

图 2:响应变慢会诱发刷新与重试,进一步放大请求量
三、过载保护的总体思路
典型互联网系统通常包含接入层、业务逻辑层和数据层。请求从接入层进入,经负载均衡分发到多个服务节点,最终访问缓存、数据库或其他下游服务。任何一层发生拥塞,都可能把压力传递给相邻层级。

图 3:典型分层系统中的请求传递路径
因此,过载保护不能只依赖某一个组件,而应形成从入口到下游的多层防线。可以归纳为四个原则:隔离影响、及早拒绝、量力而为、动态调节。
四、过载保护的四种核心方法
4.1 隔离影响:让局部故障止于局部
隔离的核心是按照业务重要性、资源消耗和故障域拆分服务,避免非核心流量拖垮核心链路。理想情况下,不同业务不仅逻辑隔离,还应在进程、线程池、连接池、机器、机房或带宽等资源层面实现隔离。
常见做法包括:
- 业务隔离:核心交易与推荐、评论、统计等非核心功能分开部署。
- 快慢隔离:快请求与慢请求使用不同线程池或队列。
- 用户隔离:按租户、用户分片或服务单元划分故障域。
- 地域隔离:按机房、区域或网络线路拆分服务。
4.2 及早拒绝:越靠近入口,保护成本越低
过载保护应遵循“前端保护后端,后端不盲目信任前端”的原则:
- 后端持续上报负载、延迟、错误率、队列长度和剩余容量。
- 接入层根据容量信息进行限流和调度,不再向过载节点发送新请求。
- 后端必须保留自我保护能力,在资源逼近上限时快速拒绝,防止请求无限堆积。

图 4:负载状态由后向前反馈,保护动作由前向后执行
拒绝请求并不等于简单返回“系统繁忙”。更好的做法是快速给出明确反馈,例如预计等待时间、排队位置或稍后重试建议。对于可以降级的请求,应返回缓存、默认值或精简结果,而不是让用户长时间等待后再超时。
同时要严格限制重试:设置超时、最大重试次数、指数退避和随机抖动,并建立全链路重试预算,避免每一层都独立重试。
4.3 量力而为:以容量基线管理系统
所有关键服务都应通过压测或 Benchmark 明确容量基线,包括最大吞吐量、稳定延迟、资源水位和性能拐点。容量规划不能按照理论峰值计算,而应保留必要冗余。
原文提出“70% 预警、90% 启动保护”的经验值,可以作为初始参考,但不应机械套用。实际阈值应结合服务特征、扩容速度、流量波动和故障恢复时间,通过压测与线上数据持续校准。
在资源有限时,应按照业务优先级分配能力:先保障登录、下单、支付等核心功能,再对推荐、评论、报表等非核心功能分级降级。
4.4 动态调节:让系统形成闭环
静态阈值只能解决已知场景,成熟的过载保护需要根据实时指标动态调整。系统应在正常、保护和恢复三个状态之间平滑切换:
- 正常状态:持续观测流量、延迟、错误率、饱和度和业务成功率。
- 保护状态:触发限流、熔断、降级、排队、背压或弹性扩容。
- 恢复状态:小流量探测并逐步放量,避免瞬间解除保护导致二次过载。

图 5:从正常运行到保护,再逐步恢复的动态闭环
五、两个常见误区
5.1 有了负载均衡和容灾,就不需要过载保护
负载均衡解决的是请求分配问题,容灾解决的是节点或机房故障后的可用性问题,它们都不能自动解决“总流量超过总容量”的问题。
当某个节点过载被摘除后,它承担的流量会转移到其他节点。如果剩余容量不足,这种转移反而会加速故障扩散。因此,负载均衡应感知节点的实时容量,而系统仍然需要限流、熔断、降级和快速失败等保护机制。
5.2 有了请求队列,就不需要过载保护
队列可以削峰和解耦,但不能创造处理能力。无界队列只会把过载从“立即失败”变成“延迟失败”,并消耗更多内存与连接资源。
如果用户已经超时并发起新请求,队列中的旧请求可能失去业务价值。后端继续按照先进先出处理这些无效请求,会浪费稀缺资源,并进一步拉长有效请求的等待时间。
因此,请求队列必须配合容量上限、超时淘汰、优先级、任务取消、幂等控制和背压机制使用。
六、落地过载保护的检查清单
- 是否通过压测明确了每个关键服务的容量基线和性能拐点?
- 是否监控延迟、错误率、流量、饱和度、队列长度和业务成功率?
- 核心与非核心业务是否拥有独立的资源池和降级策略?
- 入口、服务端和下游是否都具备限流或快速拒绝能力?
- 超时、重试、熔断和恢复策略是否能够协同工作?
- 队列是否有长度上限、过期淘汰、优先级和任务取消机制?
- 保护触发后是否有明确的用户提示、监控告警和人工干预入口?
- 恢复时是否采用灰度放量,避免流量瞬间回灌?
总结
过载保护本质上是一套容量约束下的风险控制机制。它承认资源存在上限,也承认极端流量无法完全避免。优秀的系统不会等到资源耗尽后被动崩溃,而会在接近性能拐点时主动隔离、限流、熔断和降级,把有限能力优先留给最重要的请求。
系统稳定性追求的并不是“永不拒绝”,而是在无法满足所有请求时,仍能以可预期、可恢复的方式提供核心服务。

浙公网安备 33010602011771号