Ubuntu 22.04 的服务器上 nginx 每隔几天就被杀一次,journalctl 里是 systemd-oomd: Killed /system.slice/nginx.service due to memory pressure,可 free -m 显示还有 3G 可用。

一开始怀疑是「ManagedOOMSwap 和 ManagedOOMMemoryPressure 的阈值设得太激进」,查了一圈,方向不对。

原因不止一个,得分开看。oomd 看的是 PSI 的 memory pressure 而不是可用内存。还有一种是swap 很小,短时间的分配峰值就触发了压力阈值。

不容易想到的是,某个 cgroup 里有进程在短时间大量分配,连累同组的 nginx。

上来先确认是谁触发了 oomd

journalctl -u systemd-oomd --since '3 days ago' | tail -30

再往下看内存压力指标而不是可用内存

cat /proc/pressure/memory

调整 oomd 的阈值和管控范围

grep -rn ManagedOOM /etc/systemd/oomd.conf /etc/systemd/system/*.d/

剩下的就是重载配置并验证 nginx 不再被杀

systemctl daemon-reload && systemctl restart systemd-oomd

这台环境是别人交接的,不少默认值被动过,只能一项项核。

同事提醒我看一下最近一次发布,时间点确实对得上。

改完先别撤,确认这几项。连续运行三天 nginx 的 PID 没变,journalctl 里没有新的 Killed 记录,/proc/pressure/memory 的 some avg10 保持在个位数。

容易忽略的是,直接关掉 systemd-oomd 会让真正的内存耗尽变成整机卡死,优先调阈值;给关键服务设 MemoryMin 比事后重启更有效。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189