你可能经历过这种场景:
接口整体 QPS 没超,机器 CPU 也还行,但一到流量上来,系统就开始变得很怪:下单卡住、支付回调排队、内部工具半天没响应,而某些没那么重要的任务倒是跑得飞快。
表面看像是系统不够扛,本质却是:任务调度策略设计不当,把该吃饱的饿着了,该限流的反而在狂吃。
这篇文章只讲一件事:
在高峰期,错误的调度策略会优先饿死哪些请求,以及应该怎么改调度和优先级,让系统在顶流量时先保护对的东西。
==================================================
一、哪些请求最容易先被“饿死”
1、长链路、跨服务的关键请求
最典型的是下单、支付、开户、审核一类长链路交易,它们通常具有这些特点:
- 一次调用要串多条服务和多个存储节点
- 对超时非常敏感,只要其中一段排队太久整条链路就会失败
- 在业务视角属于必须成功的动作,失败一次就要补一次
调度设计不当时,经常出现这种情况:
- 所有任务共享同一组线程池或连接池
- 批量任务和报表把线程占满
- 交易请求一直排在队尾,轮到时整条链路已经超时
你看到的是下单错误率飙升、支付回调延迟,本质是关键请求被挤到队尾,在队列里被饿死。
2、同步请求和用户交互请求
第二类是和用户交互直接相关的同步请求,例如:
- 登录、拉列表、看详情
- 点完就期待一两秒内有反馈的接口
如果调度层只看任务数量,不看任务类型,就会发生:
- 大量异步任务和同步接口抢同一批资源
- 调用同步接口的线程排队等待异步任务处理完
- 用户侧只能看到界面一直在转圈,最后直接关闭页面
技术上请求还活着,体验上早就算是被饿死了。
3、内部管理、风控和监控请求
还有一类经常被忽视:
- 内部运维面板、风控规则刷新、告警系统
- 运行状态观测接口和管理后台请求
调度不当时,这些任务常被和报表、采集放在同一队列:
- 高峰期报表导出和全量扫描占满资源
- 结果一出事,运维工具打不开,风控规则刷不动
- 原本可以快速止血的小故障,只能一路扩散成大事故

==================================================
二、哪些调度“坑”会把高峰变成“饿死场”
1、所有任务共用同一套线程池
最常见的坑是线程池全混在一起:
- Web 请求、异步消费、定时任务共享一个线程池
- 线程数只按平均并发粗略估算
高峰时会出现:
- 可以慢一点的任务把线程占满
- 真不能慢的关键请求排不到号
- 最终看到的只是线程池耗尽和队列已满的告警
2、没有优先级的统一队列
第二个坑是消息队列不分级:
- 所有任务丢进同一个消息队列
- 消费端不区分任务类型,一律先到先服务
结果很典型:
- 营销推送、日志清洗、数据修复和支付、下单一起排队
- 消费速度一旦跟不上,关键业务和杂活一起堆积
- 高峰时谁先被处理完全看运气
3、重试策略只看失败次数
还有一种隐蔽的放大器是重试:
- 写法是失败就立即重试若干次
- 不区分任务类型和失败原因
高峰期时:
- 某个下游轻微抖动,会引发大规模重试
- 重试和新请求一起抢资源,队列迅速塞满旧任务
- 下游刚恢复,上游还在发上一轮重试,把下游再次打爆
==================================================
三、怎么重排调度策略先保护对的请求
1、按业务价值给任务分三档
先别急着调线程数,先给任务贴标签,至少拆三档:
- 高优任务
登录、下单、支付、退款、店主后台和收款后台关键操作 - 中优任务
报表查询、库存同步、普通配置更新 - 低优任务
全量采集、历史补抓、统计脚本和内部工具调用
这一步是后面所有设计的前提:谁必须优先成功,谁可以延迟,谁可以直接舍弃。
2、线程池和队列按优先级拆层
拆法可以很直接:
- 高优任务使用独立线程池和独立队列
- 中优任务用单独的线程池
- 低优任务统一归入一组闲时线程池
调度规则保持简单:
- 高优线程池一直预留余量,宁肯轻载也不能抖动
- 中优只在高优负载不高时充分跑,高优一忙就主动降速
- 低优只在系统较空闲时运行,高峰时可以主动暂停或严格限流
这样高峰时最容易被饿死的会是低优任务,而不是用户下单和支付。
3、重试策略按任务类型区分
重试不能只看次数,还要看对象:
- 高优任务
少量快速重试,如果仍失败就告警并交给人工处理,避免高峰期疯狂重试把系统拖死 - 中优任务
使用间隔逐步拉长的退避策略,给系统一点恢复空间,失败次数达到上限可以延后到下一时间窗再处理 - 低优任务
重试次数少且间隔长,真失败就留到下一轮任务重跑,不要塞满队列
==================================================
四、代理和出口资源也要跟着调度分层
1、出口分组配合任务等级
如果你还在用统一出口,同时在高峰时跑采集、监控和脚本,那么调度层的分级还需要代理层一起配合,系统才会真正稳下来。
一个实用的搭法,是用易路代理做统一出口层,把线路按用途和优先级拆成几组:
- 高优业务出口组
给下单、支付、后台等关键请求使用,优先选择更稳的住宅线路或高质量机房线路,控制单条 IP 的并发和总 QPS - 中优出口组
给报表和同步使用,可以用住宅加稳定机房的组合 - 低优出口组
给采集和脚本任务使用,以机房线路为主,承接大部分可降级流量
应用配置里只需绑定任务等级与对应出口标签,而无需在代码里写死 IP。
配合易路面板上的线路组延迟、成功率和用量统计,可以随时观察哪一组被打满,决定是加线、限流还是挪任务。
2、从今天可以先做的事
你可以先做三件小事:
- 把现有任务按高、中、低三档粗略划分
- 为每档任务指定各自使用的出口组,把关键任务从采集用线里硬拆出来
- 根据易路线路组的统计数据,逐步给不同任务档位分配合理的 QPS 和并发额度
哪怕只做到这一步,高峰稳定性通常也会有明显提升。