关键不是等“内存泄漏”字样,而是识别“worker process x exited on signal 9”、upstream超时、too many open files、debug日志中pool alloc激增等间接信号,再结合dmesg中“killed process nginx”及access.log请求特征交叉验证定位。

排查 Nginx 错误日志中的内存分配异常,关键不是等它写“内存泄漏”或“OOM”,而是识别由内存压力引发的**间接行为信号**,再结合系统层日志交叉验证。
盯住 signal 9 和 killed 进程线索
当 Linux OOM Killer 杀掉 Nginx worker 时,error.log 不会主动报错,但会留下被动痕迹:
- 搜索 “worker process X exited on signal 9” 或 “Killed” —— 这是进程被强制终止的明确标志
- 同步执行 dmesg | grep -i "killed process nginx",确认内核是否输出类似 “Out of memory: Kill process 12345 (nginx)”
- 比对两处日志的时间戳,锁定具体 worker PID 和发生时刻,避免误判为正常 reload(如 “exited with code 0”)
关注高频出现的间接超时与资源耗尽提示
内存紧张常导致事件处理延迟或资源复用异常,error.log 中会出现非直接但高度相关的线索:
- “upstream timed out” 频繁出现,且后端实际响应正常 → 可能因内存不足导致事件循环卡顿、定时器失准
- “accept() failed (24: Too many open files)” 与内存占用持续升高并存 → 句柄泄露往往伴随内存未释放(如连接池堆积、缓存未清理)
- 开启 debug 日志后,“pool alloc” 或 “http cleanup add” 日志量激增 → 表明内存频繁分配但回收滞后
检查配置引发的隐性内存暴涨
某些配置错误不会立即崩溃,却会让特定请求触发失控的内存分配:
- 大量 “client intended to send too large body” 或 “request header or cookie too large” 400 报错 → 客户端持续发送超大请求,Nginx 缓冲区持续堆积未释放内容
- 集中出现在少数 worker 的 “SSL_do_handshake() failed” → 可能是 ssl_session_cache 配置过大或命中率极低,导致握手退化并反复申请堆内存
- 检查 limit_conn_zone / limit_req_zone 中 zone 大小是否为 0 或缺失 → 虽不写入 error.log,但会导致启动失败,间接影响内存行为稳定性
联动 access.log 锁定可疑请求模式
单看 error.log 很难定位源头,必须结合 access.log 分析请求特征:
- 在 signal 9 时间点前后,筛选 access.log 中响应时间异常长(>5s)、body_size 极大(>10MB)、或 user_agent 异常的请求
- 统计同一 IP 或同一 URI 的请求频次,确认是否存在扫描、重试或恶意构造请求行为
- 对比正常时段与异常时段的请求分布,观察是否某类 location 或 upstream 配置被高频触发











