nginx内存占用过高主因是worker进程rss异常,需用ps命令定位高rss worker,结合ss、access.log分析连接与请求不均,检查buffer参数及缓存配置是否超标。

排查和优化 Nginx 内存占用过高,核心是区分 Master 与 Worker 进程的角色——Master 几乎不占内存,真正消耗物理内存(RSS)的是每个独立运行的 Worker 进程。单个 Worker 内存异常升高,往往不是配置写错,而是连接分布、缓冲区分配或模块行为在负载下被放大。
快速定位高 RSS 的 Worker 进程
先确认哪些进程实际吃内存:
- 用 ps -C nginx -o pid,ppid,rss,comm --sort=-rss 查看所有 nginx 进程,按 RSS 降序排列;Master 的 PPID 是 1 或 systemd,Worker 的 PPID 是 Master 的 PID
- 更精准:执行 ps -o pid,rss,vsz,comm -p $(pgrep -P $(pgrep nginx)) | sort -k2 -nr,只列出 Worker 并排序
- 若某 Worker RSS 明显高于其他(例如高出 2 倍以上),重点盯它——可能承载了过多连接、大请求体或缓存压力
检查连接与请求是否不均或过大
Worker 内存不均常源于流量调度失衡或特殊请求类型:
- 用 ss -tnp | grep :80 | awk '{print $7}' | cut -d',' -f2 | cut -d'=' -f2 | sort | uniq -c | sort -nr 粗略统计各 Worker 处理的连接数,看是否集中在少数几个上
- 查 access.log 中对应时间窗口的大请求:需提前开启 $request_length 或 $body_bytes_sent 字段记录;上传类请求(如 POST + 文件)会触发 client_body_buffer_size 分配,单次可能占几 MB
- 若使用 proxy_cache / lua_shared_dict,注意 slab 分配器预占内存页的特性——pmap 或 ps 显示的 RSS 可能包含尚未实际使用的页,不代表真实泄漏
核对关键缓冲区与连接配置是否超标
每个连接都会按配置单独分配缓冲区内存,容易被低估:
- 估算理论最小内存:worker_connections × 0.4–0.5 KB × worker_processes;若单 Worker RSS 超过 800 MB,大概率是 buffer 参数过大
- 重点检查:client_body_buffer_size(上传体)、large_client_header_buffers(每个请求头最多可占 64 KB)、proxy_buffers(每个后端响应最多占 128 KB)、ssl_buffer_size
- 临时防护:加 worker_rlimit_as 512m 限制单 Worker 虚拟内存上限,配合系统级 ulimit -v 更稳妥
持续观察与基线对比
内存问题多具时序性,瞬时快照易误判:
- 运行 watch -n 3 'ps -C nginx -o pid,rss,comm --sort=-rss | head -6',每 3 秒刷新,观察 RSS 是否缓慢、持续爬升(典型泄漏特征)
- 用 pmap -x [worker_pid] | tail -10 查内存映射分布,关注 anon-rss 和 mapped 区域是否异常增长
- 结合 ipcs -m | grep nginx 检查共享内存段,grep -r "proxy_cache\|fastcgi_cache" /etc/nginx/ 确认缓存路径与大小设置是否合理











