一、排查流程
1. 确认内存占用情况
使用 top
或 ps
命令查看 nginx 进程内存占用:
top -p $(pgrep nginx | tr '\n' ',') # 实时查看 nginx 进程 ps -o pid,rss,command -p $(pgrep nginx) # 查看 rss(实际物理内存)占用
使用 pmap
分析单个进程内存分布:
pmap -x $(pgrep nginx | head -n1) | tail -n 10 # 查看内存映射
2. 分析内存占用类型
共享内存(shm):
# 查看共享内存段 ipcs -m | grep nginx
缓存内存:
# 检查 proxy_cache 或 fastcgi_cache 配置 grep -r "proxy_cache" /etc/nginx/
3. 检查 nginx 配置
查看是否启用高内存消耗模块:
# 检查是否启用 large_client_header_buffers large_client_header_buffers 4 16k; # 每个请求可能占用 64kb # 检查 proxy_buffer 配置 proxy_buffers 8 16k; # 每个连接可能占用 128kb
4. 分析日志与监控数据
检查错误日志:
tail -f /var/log/nginx/error.log | grep -i "memory"
- 使用监控工具(如 prometheus + grafana)收集内存指标:
- 总内存使用量
- 每个 worker 进程内存使用
- 缓存命中率
二、常见原因与处理方法
1. 工作进程(worker)过多
- 问题表现:多个 worker 进程占用大量内存
- 解决方法:
# 根据 cpu 核心数调整 worker 数量 worker_processes auto; # 自动匹配 cpu 核心数
2. 单个请求内存消耗过大
- 问题表现:处理大文件或大请求时内存激增
- 解决方法:
# 减小缓冲区大小 client_body_buffer_size 8k; # 客户端请求体缓冲区 large_client_header_buffers 4 8k; # 请求头缓冲区 # 限制上传文件大小 client_max_body_size 10m;
3. 缓存配置不合理
- 问题表现:proxy_cache 或 fastcgi_cache 占用过多内存
- 解决方法:
# 优化缓存参数 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m; proxy_cache_key "$scheme$request_method$host$request_uri"; # 限制单个缓存项大小 proxy_cache_max_range_offset 1m;
4. 内存泄漏或第三方模块问题
- 问题表现:内存持续增长不释放
- 解决方法:
# 启用内存调试(编译时添加 --with-debug) error_log /var/log/nginx/error.log debug; # 逐步禁用第三方模块,定位问题模块
5. ssl 会话缓存配置不当
- 问题表现:https 流量大时内存占用高
- 解决方法:
# 优化 ssl 会话缓存 ssl_session_cache shared:ssl:20m; # 减少共享内存大小 ssl_session_timeout 10m; # 缩短会话超时时间
三、内存优化建议
1. 调整工作进程内存分配
# 限制每个 worker 进程的最大内存使用(需要 nginx-plus 或第三方模块) worker_rlimit_nofile 65535;
2. 使用内存限制工具
# 使用 cgroups 限制 nginx 进程组内存 echo "1000000000" > /sys/fs/cgroup/memory/nginx/memory.limit_in_bytes # 限制为 1gb
3. 优化静态资源处理
# 禁用不必要的静态资源缓冲区 location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { sendfile on; tcp_nopush on; expires 7d; access_log off; add_header cache-control "public"; }
4. 使用 swap 分区作为缓冲
# 创建 swap 文件(8gb 示例) dd if=/dev/zero of=/swapfile bs=1g count=8 chmod 600 /swapfile mkswap /swapfile swapon /swapfile # 调整 swappiness 参数(0-100) echo 10 > /proc/sys/vm/swappiness
四、应急处理措施
1. 临时减少并发连接
# 限制每个 ip 的并发连接数 limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn perip 20; # 每个 ip 最多 20 个连接
2. 关闭高内存消耗功能
# 临时关闭缓存 proxy_cache off; # 临时关闭 ssl 会话缓存 # ssl_session_cache shared:ssl:20m; → 注释掉此行
3. 重启 nginx 释放内存
# 平滑重启(不中断服务) nginx -s reload # 强制重启 systemctl restart nginx
五、验证优化效果
1. 压力测试对比
# 使用 wrk 进行压力测试 wrk -t12 -c400 -d30s http://example.com/ # 对比优化前后内存增长曲线
2. 长期监控指标
- 内存使用率趋势图
- 单个请求内存消耗分布
- oom(out of memory)事件记录
3. 内存泄漏检测
# 使用 valgrind 检测内存泄漏(仅建议在测试环境使用) valgrind --leak-check=full --show-leak-kinds=all /usr/sbin/nginx -g "daemon off;"
通过以上步骤,可以系统性地排查和解决 nginx 内存占用过高问题,同时建立长效的内存监控机制,避免因内存问题导致服务中断。
以上就是nginx内存占用过高排查与处理过程的详细内容,更多关于nginx内存占用过高的资料请关注代码网其它相关文章!
发表评论