先执行dmesg -T | grep -i "killed process"确认OOM Killer杀进程的硬证据,再比对Nginx error.log中"exited on signal 9"及"upstream prematurely closed connection"时间点,结合ps aux --sort=-%mem和/proc/PID/smaps验证worker内存异常增长。

直接看内核日志找“被杀证据”,再比对 Nginx 日志和进程状态,就能快速确认是不是 worker 进程因内存越界被 OOM Killer 干掉。
查 dmesg 确认是否真被 OOM 杀掉
这是最硬的证据,不能只看 Nginx 自己的日志:
- 运行 dmesg -T | grep -i "killed process",重点找含 nginx、worker 或具体 worker PID 的行,例如:
"Killed process 12345 (nginx) total-vm:8901234kB, anon-rss:3845678kB" - 如果输出里有时间戳,并且和故障发生时间吻合,基本就是 OOM 导致的
- 补充查 /var/log/syslog 或 /var/log/messages,搜索 "Out of memory: Kill process",交叉验证
对照 Nginx error.log 找同步异常信号
Nginx 不会写“OOM”,但会留下被杀后的痕迹:
- 在 error.log 中搜索 "exited on signal 9" 或 "Killed",signal 9 就是 kill -9,通常对应 OOM 终止
- 注意区分:"exited with code 0" 多是正常 reload;而 "exited on signal 9" + 时间点匹配 dmesg,就是强关联
- 同一时刻若还集中出现 "upstream prematurely closed connection"(不是 connection refused),说明后端 worker 消失得非常突然,也符合 OOM 特征
看实际内存占用和增长趋势
光看“有没有被杀”不够,还要确认“为什么被杀”:
- 用 ps aux --sort=-%mem | head -10 查 RSS 最高的进程,确认是不是 nginx worker,以及是否持续上涨(比如从 200MB 涨到 4GB)
- 对某个高 RSS 的 worker,执行 cat /proc/PID/smaps | awk '/^Rss:/ {sum += $2} END {print sum " kB"}',看真实物理内存使用
- 如果是长连接场景(如 WebSocket),重点关注 Send-Q/Recv-Q 堆积 和 连接数是否接近 worker_connections 上限,堆积会导致缓冲区内存暴涨
临时防护与定位方向建议
确认是 OOM 后,先稳住服务,再深挖根因:
- 给 nginx worker 加资源限制:在 systemd service 文件中设 MemoryMax= 或调整 /proc/sys/vm/overcommit_memory
- 检查是否有模块或配置引发内存泄漏:比如开启 debug 日志后大量出现 "pool alloc"、"http cleanup add";或错误使用 map、geo 指令导致哈希表无限膨胀
- 压测或高峰时段用 pmap -x PID 或 gcore 抓内存快照,分析大内存块归属(如 anon-rss 高但 file-rss 低,说明是堆分配而非文件缓存)


















