Nginx error.log不直接记录“OOM”,但通过“worker process X exited on signal 9”、upstream超时、too many open files、debug日志中pool alloc激增等异常线索,结合dmesg中“killed process nginx”输出及access.log请求特征,可交叉定位内存泄漏源头。

盯住 OOM killer 留下的痕迹
当 worker 进程因内存不足被系统强制终止时,Linux 内核会写入 dmesg 日志,而 Nginx 的 error.log 往往同步出现“worker process X exited on signal 9”或“killed due to out of memory”。这不是 Nginx 主动报错,而是它被杀掉后的被动记录。
- 执行 dmesg | grep -i "killed process" | grep nginx,确认是否有类似 "Out of memory: Kill process 12345 (nginx) 的输出
- 在 error.log 中搜索 "exited on signal 9" 或 "Killed",按时间戳比对 dmesg 记录,锁定具体 worker PID 和发生时刻
- 注意:如果只看到大量 "worker process X exited with code 0",大概率不是 OOM,而是正常 reload 或配置热更新
排查高内存占用 worker 的异常行为线索
部分 worker 进程 RSS 持续飙升,但尚未被 kill,此时 error.log 可能留下间接线索:
- 反复出现 "upstream timed out"(尤其伴随后端实际响应正常),可能因内存紧张导致事件循环卡顿、超时误判
- 大量 "accept() failed (24: Too many open files)" 与内存增长并存,提示句柄泄露常伴生内存泄漏(如缓存未释放、连接池堆积)
- 开启 debug 日志(error_log /path/error.log debug;)后,可观察到 "http cleanup add"、"pool alloc" 类高频日志激增,暗示内存分配活跃但未及时回收
排除配置/模块引发的内存暴涨假象
某些错误配置不会立即崩溃,却让 worker 在特定请求下疯狂分配内存:
- 搜索 "client intended to send too large body" 或 "request header or cookie too large" —— 这类 400 错误若高频出现,说明客户端正不断发送超大请求,Nginx 缓冲区持续堆积未清理内容
- 出现大量 "SSL_do_handshake() failed" 且集中在某几个 worker,可能是
ssl_session_cache配置过大或命中率极低,导致 TLS 握手退化并反复申请堆内存 - 自定义模块报错如 "lua entry thread aborted: memory not enough"(OpenResty 场景),直接指向 Lua 层内存失控
关联访问日志缩小可疑请求范围
单靠 error.log 不足以定位泄漏源头,必须联动 access.log:
- 确保 log_format 包含
$request_length和$bytes_sent,找出那些请求体极大、响应体极小的请求(典型缓冲区滞留特征) - 筛选出 error.log 中出问题的时间段,提取对应 access.log 中的 URI 和 $http_user_agent,看是否集中于某个接口、某个 SDK 版本或某类爬虫
- 若发现特定 Cookie 值反复出现在失败请求中,用
strings分析其内容长度和结构,判断是否为前端埋点注入的长文本造成解析阶段内存堆积


















