压缩风暴:Session 过多饿死关键 Cron
本文最后更新于 2026年7月28日 下午
凌晨三点,MCP 服务器本该最安静,却最拥挤。
韩梅梅跑了日记,小美还在监控舆情,贾维斯开了一整晚的代码优化 session,露西的采集任务也刚醒来。它们各不相干,却在同一个 Hermes 实例下抢同一个 session 池。结果是:心跳、日记、日报这类关键 cron 明明到点了,却迟迟不启动,或者说,它们排了队,却在 session 资源被占满的时候被饿着等。
这篇写的是同一个系统的另一面:之前我们聊过 50 个 cron 的错峰治理,聊过 collect_cron_results 的假阴性,也聊过 FIFO 把 P1 任务堵在队尾的问题。今天要讲的是更底层的资源竞争——当 session 数本身成了瓶颈,再好的调度逻辑也没地方跑。
什么是”压缩风暴”
“压缩风暴”这个名字形容的是现象本身:多个 profile 的 cron 和长 session 在同一台机器上叠罗汉。每个 profile 都有自己的一套定时任务——韩梅梅管投资、日报、日记;小美管舆情、内容;露西管数据采集;贾维斯管远程代码优化——它们各自看起来都不算多,但叠在一起,并发量会迅速吃掉 Hermes Worker 的可用 session 名额。
一旦可用 session 名额被占用完,新的 cron 触发后并不会直接报错,它可能进入等待状态,或者在 session 池满的时候根本拿不到一个可执行的 session。对心跳、日记、日报这类”定时必须发生”的任务来说,这很麻烦:它不是代码 bug,不是网络失败,而是系统资源被别的合法任务挤占,结果本该准点运行的任务被静默延迟。
这跟之前写的 FIFO 陷阱不是同一回事。FIFO 是队列顺序问题,P0 任务被 P2 任务排在前面;而这里的根因是容量问题:session 池本身不够分,无论怎么排,池子满的时候大家都要等。
现场长什么样
典型表现是:某个 cron 的触发时间到了,但下一周期的任务先跑完了,或者日志里能看到触发记录,却没有对应的 session 执行结果。另一个常见信号是:系统同时在线的 session 数已经很高,worker 状态里活跃 interaction 和仍在交互的 session 数量长期接近某个隐式上限。
在 Hermes 里,第一步不是去查 cron 配置,而是查 worker。hermes_studio_use_worker_status(或 Hermes Web UI 里对应的 worker status 接口)能告诉你当前 worker 数量、已完成 interaction 数,以及还有多少 session 仍在交互。如果你看到活跃 session 长期处于高位,而 cron 触发后迟迟不见新 session 启动,这就很像容量竞争。
第二步,用 session 列表做横向统计。hermes_studio_use_sessions_list 能看到近期 session,配合按 profile、source 或时间窗口做简单计数,就能判断高峰出现在什么时段、哪些 profile 贡献了最多的并发。实际经验里,高峰往往不是白天,而是凌晨——多个 cron 按整点唤醒,长 session 又没及时关闭,两个流量撞在一起,就是最容易出问题的时刻。
诊断方法:看队列,也看池子
诊断时不要只盯一个维度。建议同时看三样东西:
- worker status:当前 worker 数量和仍活跃 session 数。这是容量维度的入口,能说明”是不是池子满了”。
- session 数统计:按 profile、source、时间段统计 session 数量。这是负载维度的入口,能说明”是谁占满了池子”。
- cron 触发与完成的时间差:对比 cron 计划时间和实际 session 启动时间。如果差异持续存在,且正好落在活跃 session 高位区间,就能把资源竞争和单纯延迟区分开。
这三步合起来,能把问题从”任务没跑”收敛到”任务因为 session 池满而饿等”。
根因:并发 session 上限
Hermes Agent 的架构里,多个 profile 共享同一个 Hermes 实例和同一套 worker。cron 触发的每一次执行,本质上都对应一个新的 session;长 session(比如一晚上持续优化的代码任务)会长期占据一个名额。当 worker 可维护的并发 session 数有限时,profile 再多、任务越多,session 池就越容易被打满。
换句话说,每个 profile 单独看都合理:韩梅梅跑日报、小美跑舆情、贾维斯跑代码优化,它们各自都有业务必要性。问题不在某个任务,而在它们共享同一张桌子——session 池没有为每个 profile 预留独立容量,也没有对关键 cron 设置绝对优先的执行通道。于是当并发上来时,最轻、最频繁、最容易被打断的心跳和日报,反而最容易被挤到后面。
缓解策略:先错峰,再隔离,最后管生命周期
针对 session 饥饿,可以按成本从低到高尝试三层方案。
第一层:cron 时间错开。 这是最快、成本最低的。把多个整点触发的 cron 按分钟偏移,比如韩梅梅日记放在 03:10,露西采集放在 03:15,贾维斯优化放在 03:25,把心跳、日报这类关键任务放到高峰之后。错开不是让任务更快,而是减少同一时刻争抢 session 的概率。这层和之前的错峰治理是同一套思路,但对”压缩风暴”尤其有效,因为它直接削峰。
第二层:profile 隔离。 如果错峰还不够,说明问题不是时间点,而是并发总量。可以考虑把关键 profile 放到独立 Hermes 实例,或至少在调度层面区分”关键通道”和”普通通道”:心跳、日报、系统巡检进入关键通道,研发优化、舆情批量、长代码 session 进入普通通道。关键通道被保障启动,普通通道在容量紧张时降级或延后。这样做的代价是运维复杂度上升,但对多 profile 共享实例长期运行来说,往往是必经之路。
第三层:session 生命周期管理。 长 session 是 session 池里最隐蔽的占用源。诊断后如果发现某些 profile 的长 session 长期不关闭,要给它设计明确的结束条件:定时关闭、任务完成即关、或者把长工作拆成多个短 session。session 生命周期一旦被管理起来,池子里的可用名额会明显释放,关键 cron 被饿死的概率也会下降。
这套经验适合谁
如果你满足以下条件,这篇内容基本可以直接用:
- 多个 AI Agent profile 共用一个 Hermes 实例
- cron 数量和长 session 同时存在,且高峰时段重叠
- 关键 cron 偶尔不按时跑,但单独查每个任务又没有明显报错
- worker status 显示活跃 session 长期处于高位
不适合的场景则相反:单 profile、任务量少、session 数低,这类环境通常不会触发容量竞争,用错峰就够了,不必搞 profile 隔离。
写在后面
“压缩风暴”的本质不是某个任务写错了,而是共享资源在并发高峰时没有优先级保护。Hermes Agent 的多 profile 协作很强大,但强大也意味着更容易在同一张桌子上挤满人。治理的关键不是减少任务,而是让资源分配变得更可见、更可控:看得到的 session 池、分得开的错峰时间、分得清的关键与普通通道。
下次凌晨三点,如果关键 cron 又没按时醒来,先别急着改代码。先看看 worker 状态和 session 列表——可能它不是死了,只是在排队等一个空位。
参考
- 零成本运维:5 人 AI Agent 团队的 cron 治理 — 错峰调度和 50 个 cron 的治理思路
- 心跳任务队列 FIFO 陷阱:P1 被 3 天挡住 — 队列顺序导致的优先级问题
- 删症状≠修根因:collect_cron_results 连续三天假阴性的教训 — 如何避免把假阴性当成根本原因
- Hermes Agent 官方文档 — worker status、session 列表与 cron 引擎说明