nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > Nginx内存占用过高

Nginx内存占用过高排查与处理过程

作者:alden_ygq

Nginx内存使用率过高就像是一场暴风雨,会给我们的网站和应用带来不小的麻烦,但只要我们能够冷静分析,找出问题的根源,对症下药,就一定能够化解危机,所以本文给大家介绍了Nginx内存占用过高排查与处理过程,需要的朋友可以参考下

一、排查流程

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"

二、常见原因与处理方法

1. 工作进程(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_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 会话缓存配置不当

# 优化 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. 长期监控指标

3. 内存泄漏检测

# 使用 valgrind 检测内存泄漏(仅建议在测试环境使用)
valgrind --leak-check=full --show-leak-kinds=all /usr/sbin/nginx -g "daemon off;"

通过以上步骤,可以系统性地排查和解决 Nginx 内存占用过高问题,同时建立长效的内存监控机制,避免因内存问题导致服务中断。

以上就是Nginx内存占用过高排查与处理过程的详细内容,更多关于Nginx内存占用过高的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文