关键在于定位高rss的worker进程,而非总内存;用ps命令筛选worker并按rss排序,结合ss和access.log分析连接与大请求分布,核查buffer参数及缓存配置是否超标。

排查 Nginx 内存占用过高,关键不是看“总内存用了多少”,而是定位哪个进程、哪类连接、哪段配置在异常吃内存。Nginx 的 Master 进程几乎不占 RSS,真正消耗物理内存的是每个 Worker 进程——问题往往藏在单个 Worker 的 RSS 突增、连接分布失衡或缓冲区配置超标里。
快速识别高 RSS 的 Worker 进程
先聚焦真实吃内存的个体:
- 运行 ps -o pid,rss,comm -p $(pgrep -P $(pgrep nginx)) | sort -k2 -nr,只列出所有 Worker 并按 RSS 降序排列
- 若某 Worker RSS 明显高于其他(比如 600MB vs 其他 80MB),它就是重点观察对象
- 配合 watch -n 3 'ps -o pid,rss,comm -p $(pgrep -P $(pgrep nginx)) | sort -k2 -nr | head -5' 每 3 秒刷新,确认是瞬时峰值还是持续爬升(后者更可能是泄漏或积压)
检查连接与请求是否异常集中或过大
Worker 内存不均,常因流量没打散,或个别请求触发大量缓冲分配:
- 用 ss -tnp | grep :80 | awk '{print $7}' | cut -d',' -f2 | cut -d'=' -f2 | sort | uniq -c | sort -nr 统计各 Worker 处理的连接数,看是否集中在 1–2 个进程上
- 查 access.log 中对应时间窗口的大请求:grep "POST" /var/log/nginx/access.log | awk '$9 > 5000000 {print $0}'(筛选 body 大于 5MB 的 POST)
- 特别注意上传类请求(如文件上传)、长 WebSocket 消息、未及时消费的响应流——它们会撑大 client_body_buffer_size 或 proxy_buffers
核对缓冲区和缓存配置是否实际超标
每个连接都会按配置独占缓冲区内存,容易被低估:
- 估算理论下限:worker_connections × 0.4–0.5 KB × worker_processes;若单 Worker RSS 超过 800 MB,极大概率是 buffer 参数设得过大
- 重点检查:client_body_buffer_size(上传体)、large_client_header_buffers(单请求头最多占 64KB)、proxy_buffers(单后端响应最多占 128KB)、ssl_buffer_size
- 临时防护:在 nginx.conf 中加 worker_rlimit_as 512m;,限制单 Worker 虚拟内存上限,防止 OOM 杀进程
分析内存映射与共享资源占用
区分真实占用和预分配/缓存残留:
- 对高 RSS Worker 执行 pmap -x [pid] | tail -10,关注 anon-rss(真实堆内存)和 mapped 区域占比
- 查共享内存段:ipcs -m | grep nginx,确认 proxy_cache、lua_shared_dict 等是否配置了过大的 keys_zone
- 检查临时文件残留:lsof -p [worker_pid] | grep deleted,若发现大量已删未释放的 proxy_temp 或 client_body_temp 文件,说明后端响应慢或客户端接收卡顿导致积压











