fix(ops): 补上 09-04 事故缺的两道兜底 —— 容器内存上限 + 外部存活探针
09-04 生产宕 11.8 小时,根因不是"内存涨了",是三道兜底同时不在:
① V8 abort —— 堆天花板 08-26 抬到 8G,还没顶到就先把机器吃穷
② cgroup OOM —— 容器 HostConfig.Memory=0,这条压根不存在
③ 内核 OOM —— 机器无 swap,file page 永远"可回收",内核宁可反复
丢/重读 page cache 也不判 OOM → refault 活锁,不留任何日志
外加告警 8 类全部由 pac-service 进程内推,进程一卡告警一起哑,
连云监控 agent 都在 20:35 被饿死 → 12 小时无人知晓。
本次两条都只买"炸得小、有人知道",不减内存:
1. docker-compose.prod.yml 给 pac-service 加 mem_limit: 8g
把爆炸半径从整机缩回单容器:越界 SIGKILL(137)→ restart:always 拉起,
回到 08-29 那次内核 OOM 的分钟级自愈。8g 由生产实测倒推:
15.36G 全机 − 2.5G(OS+page cache,无 swap 挤不得) − 2.7G(dockerd 压力峰值)
− 0.2G(web+docs) ≈ 10G 可用,观测峰值 6.03G,取 8G 留 33% 余量。
⚠ ️ 暂不动 NODE_OPTIONS 的 8192:等分批改造的 heapUsed= 日志给出生产实测峰值,
再把堆上限压到 mem_limit 之下,让 V8 先自己抛(有堆栈)而不是被 SIGKILL(无日志)。
2. deploy/health-watch.sh —— 装在**被监控机之外**的 cron 探针
连续 N 次 /health 不通才告警,恢复也推一条;带对照探针防探针机断网误报;
纯 bash+curl 无额外依赖;永远 exit 0 不给 cron 制造邮件。
3. 顺带修 deploy-prod.sh 的 health 验证一直在空转
真实路由是 /health(GLOBAL_PREFIX_EXCLUDE,不带 /pac/v1),
而全局响应拦截器把 404 也包成 HTTP 200:
/pac/v1/health → 200 {"code":10004,"msg":"Cannot GET /pac/v1/health"}
于是"只看 %{http_code}"的探活恒真 —— 三项硬验证里的 health 那项
只证明了 Nest 的 HTTP 层还在应答。改为探 /health 且判据落在 body 上。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Showing
deploy/health-watch.sh
0 → 100755
Please
register
or
sign in
to comment