Nginx内存占用过高需聚焦Worker进程RSS异常增长,通过ps筛选高RSS Worker、ss和access.log分析连接与请求分布、检查缓冲区配置及缓存预占,并用watch/pmap/smaps持续观察内存变化趋势。

排查 Nginx 内存占用过高,核心是聚焦 Worker 进程的 RSS(实际物理内存)异常增长,而非 Master 进程——它几乎不占内存。问题通常不是配置写错,而是连接分布不均、缓冲区被大量请求触发分配、缓存机制预占内存,或模块行为在高负载下被放大。
快速定位高 RSS 的 Worker 进程
先筛出真正吃内存的进程:
- 运行
ps -C nginx -o pid,ppid,rss,comm --sort=-rss,按 RSS 降序排列所有 nginx 进程;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 倍以上),重点盯它——可能承载了过多长连接、大请求体或缓存压力
检查连接与请求是否失衡或过大
内存不均常源于流量调度偏差或特殊请求类型:
- 用
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区域变化 - 结合
cat /proc/[pid]/smaps看具体内存段归属,区分是 socket 缓冲区、共享字典还是匿名堆内存增长



















