exit_code 137 或 signal 9 是 Nginx 因 OOM 被内核强制终止的明确信号,需结合 dmesg 确认“Killed process nginx”、access.log 分析大请求/高频 SSL/超长 header,并排查 ssl_session_cache、client_max_body_size 等隐性内存配置。

直接看 error.log 里有没有 “exited on signal 9” 或 “exited with code 137”,这是内存不足被系统强制杀掉的最明确信号。但光看这一条不够,必须联动系统日志和请求日志交叉验证。
锁定 error.log 中的关键退出线索
Nginx 自身不会写“内存不足”,但进程被 OOM Killer 终止时,会留下不可忽略的痕迹:
- worker process [0-9]+ exited on signal 9 → 几乎等同于被内核 kill(SIGKILL)
- worker process [0-9]+ exited with code 137 → 137 = 128 + 9,含义与 signal 9 完全一致
- accept() failed (24: Too many open files) → 常与内存紧张并存:连接结构体分配失败,导致句柄复用异常
- upstream timed out(后端实际响应正常)→ 内存压力下事件循环延迟、定时器失准的典型表现
立即比对 dmesg 确认是否真被 OOM Killer 干掉
signal 9 只是结果,dmesg 才是源头证据。执行:
dmesg -T | grep -i "killed process" | grep nginx
若输出类似:
[Mon Sep 5 10:22:18 2026] Out of memory: Kill process 12345 (nginx) score 892 or sacrifice child
→ 就坐实了是内存耗尽触发系统级拦截。注意比对时间戳是否与 error.log 中 signal 9 时间接近(误差一般在±30秒内)。
结合 access.log 找出压垮内存的请求特征
OOM 往往不是平均负载高,而是某类请求集中触发单 worker 内存暴涨。在 signal 9 发生前后 1–2 分钟内检查 access.log:
- 是否存在大量 POST body > 10MB 的上传请求?Nginx 缓冲区堆积不释放会快速吃光内存
- 是否有固定 IP 在短时间发起 高频 SSL 握手(如每秒数十次)?ssl_session_cache 配置不当会退化为每次全量堆分配
- 是否密集出现 “request header or cookie too large” 错误?超长头持续占用未清理的缓冲区
- 响应时间异常长(> 5s)且集中在某个 worker 进程 ID?说明该 worker 已陷入内存分配/回收瓶颈
检查配置中容易被忽略的隐性内存消耗点
某些看似无害的配置,在高并发或异常请求下会成为内存放大器:
- ssl_session_cache 设得过大(如 100m)且命中率极低 → 每次握手都新建 session 对象,堆内存线性增长
- client_max_body_size 过大(如 1G),但未配 client_body_buffer_size → 大文件直接落磁盘前仍需内存缓冲
- proxy_buffering on + large proxy_buffers → 后端响应慢时,整个响应体缓存在内存中,极易撑爆
- limit_conn_zone / limit_req_zone 的 zone 大小设为 0 或缺失 → 虽不报错,但会导致连接跟踪逻辑异常,间接引发内存管理紊乱


















