先查dmesg确认是否被OOM Killer杀死,再核对error.log中“exited on signal 9/11”时间戳,结合access.log异常请求与core dump堆栈交叉定位根因。

排查 Nginx 进程频繁异常崩溃,不能只盯着 error.log 里有没有“crash”字样——真正关键的日志分散在系统底层,需要分层抓取、交叉比对。核心思路是:先确认是不是被系统强制杀掉,再锁定触发时机,最后回溯到具体请求或配置行为。
看 dmesg 确认是否被 OOM Killer 干掉
Linux 内核在内存不足时会主动杀死进程,Nginx worker 是常见目标。这个动作不会写进 Nginx 日志,但会在内核日志留下明确记录:
- 运行
dmesg -T | grep -i "killed process nginx",找类似这样的输出:[Tue Jul 29 09:15:22 2026] Out of memory: Kill process 18432 (nginx) score 872 or sacrifice child - 如果匹配成功,说明是内存耗尽导致的被动终止,下一步重点查内存分配异常(比如缓存未释放、大 body 积压、ssl session cache 配置过大)
- 同时检查
free -h和cat /proc/meminfo | grep -i "oom\|commit",确认当时内存压力水平
查 error.log 中的 signal 退出线索
Nginx 自身日志虽不记原因,但会忠实记录结果。重点关注以下两类行:
-
worker process 12345 exited on signal 9→ 基本等于被 OOM Killer 杀;exited on signal 11→ 段错误,多为模块 bug 或内存越界 -
worker process 12345 exited on signal 11 (core dumped)→ 表示已生成 core 文件,可配合 gdb 分析真实崩溃点 - 注意时间戳对齐:把 signal 出现的时间,和 dmesg 中的 kill 时间、access.log 中的慢请求/大请求时间做三重比对
启用并定位 core dump 文件
Signal 11 类崩溃必须靠 core 文件才能定位根因:
- 先确保开启:
ulimit -c unlimited,并在/etc/security/limits.conf中为 nginx 用户配好nginx soft core unlimited - 查 core 路径:
cat /proc/sys/kernel/core_pattern,常见两种情况:
• 输出core→ 文件在 Nginx 工作目录(通常是/usr/local/nginx或/etc/nginx)
• 输出|/usr/lib/systemd/systemd-coredump %P...→ 文件在/var/lib/systemd/coredump/,后缀是 .xz - 用
gdb $(which nginx) /path/to/core,然后输入bt full查看崩溃堆栈,重点关注第三方模块(如 lua、echo、headers-more)调用位置
结合 access.log 锁定异常请求模式
很多崩溃不是随机发生,而是由特定请求持续触发:
- 在 signal 发生前后 30 秒内,提取 access.log 中响应时间 >5s、body_size >10MB、或 user_agent 含扫描特征(如 sqlmap、dirbuster)的请求
- 统计高频 URI 或 IP:
awk '$9 > 5000 {print $7}' access.log | sort | uniq -c | sort -nr | head -10(找响应超长的路径) - 特别关注反复出现的 400 错误:
"client intended to send too large body"或"request header too large",这类请求会让 Nginx 缓冲区持续堆积,最终拖垮 worker











