docker-compose.prod.yml
12.6 KB
-
fix(ops): 补上 09-04 事故缺的两道兜底 —— 容器内存上限 + 外部存活探针 · 6cb7b2f6
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>luoqi committed