nginx worker进程内存分析需聚焦rss值,通过ps、pmap定位高内存worker及anon匿名映射增长,结合缓冲区配置、共享内存和连接数交叉验证,排除正常负载后判断是否泄漏,并建立prometheus监控与告警。

分析 Nginx Worker 进程内存占用,核心是区分“谁在用内存”和“为什么用这么多”,而不是只看一个总数。Master 进程几乎不占内存,真正要盯的是每个 Worker 进程的 RSS(常驻物理内存),它反映实际消耗的 RAM。
快速定位高内存 Worker
用系统命令直接查进程级内存,最准也最快:
-
按 RSS 排序列出所有 nginx 进程:
ps -C nginx -o pid,ppid,rss,vsz,comm --sort=-rss—— 看哪几个 Worker 的 RSS 明显高于其他(比如超 300MB) -
只查 Worker PID 并输出内存 KB 数:
pgrep -P $(pgrep nginx) | xargs -r ps -o pid,rss= -p 2>/dev/null—— 方便脚本后续处理 -
持续观察变化趋势:
watch -n 3 'ps -C nginx -o pid,rss,comm --sort=-rss | head -6'—— 每 3 秒刷新一次,看 RSS 是否缓慢爬升或突增
深入看内存分布(确认是否真泄漏)
RSS 高不等于有问题,得看内存花在哪。用 pmap 查单个 Worker 的内存映射:
-
pmap -x <strong>WORKER_PID</strong>—— 关注最后一行的 mapped(总映射)、written(已写入物理页)、shared(共享库占用) - 重点看 anon(匿名映射,通常是堆、mmap 分配)是否随时间增长;若它持续变大而请求量没变,就可能是模块或 Lua 脚本未释放内存
- 对比多个 Worker 的 pmap 输出:如果只有某一个 anon 异常高,大概率是该 Worker 处理了异常请求(如超大 body、死循环 Lua)
结合配置与运行时状态交叉验证
光看进程不够,要对照 nginx 实际怎么配、怎么跑:
-
检查缓冲区配置:执行
nginx -T 2>/dev/null | grep -E "(client_|proxy_|fastcgi_|gzip)_buffer"—— 若client_body_buffer_size 128k且并发高,每个活跃连接最多可能占 128KB 缓冲 -
确认共享内存使用:
ipcs -m | grep nginx—— 查看 limit_req、ssl_session_cache 等共享段是否过大(比如设了 128M 却只用 5MB,RSS 不会体现,但 VSS 会高) -
看连接活跃度:
ss -s | grep -i "nginx\|tcp"或netstat -ant | grep :80 | wc -l—— 如果连接数很低但 RSS 很高,更倾向内存泄漏;如果连接数飙升时 RSS 同步涨,属于正常负载响应
生产环境可持续观测建议
手动查适合排查,长期监控得自动化:
- 写个简单脚本每分钟采集所有 Worker 的 RSS,计算最大值/平均值,推送到 Prometheus 的 textfile collector
- 设置告警阈值:例如任一 Worker 的 RSS > 400MB 持续 5 分钟,触发 reload(旧 Worker 会自然退出释放内存)或发钉钉告警
- 搭配日志分析:开启
error_log /var/log/nginx/error.log warn;,配合grep "out of memory\|segfault" /var/log/nginx/error.log快速捕获崩溃线索











