Nginx资源占用过高(主要表现为CPU、内存占用飙升)通常与配置不合理、系统参数限制或模块问题有关。以下是系统性解决步骤:
在优化前,需明确是CPU占用过高还是内存占用过高,以及具体原因:
top -p $(pgrep nginx | tr '\n' ',')
实时查看Nginx进程的CPU/内存占用;ps -o pid,rss,command -p $(pgrep nginx)
查看每个进程的实际物理内存(RSS)使用情况。pmap -x $(pgrep nginx | head -n1) | tail -n 10
查看单个Nginx进程的内存映射,识别是否有异常大的内存段(如共享内存、缓存)。large_client_header_buffers
、proxy_buffer
),或配置了过大的缓冲区(如client_body_buffer_size
、proxy_buffers
)。CPU占用高通常与工作进程配置、连接数限制、SSL处理有关:
worker_processes
设置为CPU核心数(或auto
,Nginx会自动匹配):worker_processes auto; # 推荐,自动适配CPU核心数
events
块中调整worker_connections
(每个worker的最大并发连接数),建议设置为1024-10000(根据服务器性能调整):events { worker_connections 4096; # 提高并发处理能力 use epoll; # 使用epoll事件模型(Linux下高性能选择) multi_accept on; # 允许一个worker同时接受多个连接 }
http
块中启用sendfile
(零拷贝传输)、tcp_nopush
(合并小包发送)、tcp_nodelay
(禁用Nagle算法,减少延迟):http { sendfile on; tcp_nopush on; tcp_nodelay on; }
ssl_session_cache shared:SSL:20m; # 共享内存缓存大小 ssl_session_timeout 10m; # 会话超时时间 ssl_protocols TLSv1.2 TLSv1.3; # 仅启用TLS 1.2/1.3(更安全且高效) ssl_ciphers HIGH:!aNULL:!MD5; # 使用高效加密套件 ssl_prefer_server_ciphers on;
内存占用高通常与缓存配置、工作进程数量、内存泄漏有关:
expires
),减少重复请求:location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; # 缓存30天 add_header Cache-Control "public, no-transform"; access_log off; # 关闭访问日志(减少IO) }
proxy_cache
参数,限制缓存大小和单个缓存项大小:proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m; # 缓存路径、共享内存大小、最大容量 proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_valid 200 302 10m; # 200/302状态码缓存10分钟 proxy_cache_use_stale error timeout updating; # 缓存过期时仍可使用(避免频繁请求后端)
worker_rlimit_nofile
限制每个worker进程的最大文件描述符数(避免内存耗尽):worker_rlimit_nofile 65535; # 推荐值(需与系统ulimit一致)
worker_memory_limit
限制每个worker的内存使用(如worker_memory_limit 512m
)。nginx.conf
中设置error_log /var/log/nginx/error.log debug;
(仅排查时开启,会产生大量日志),观察内存是否持续增长。valgrind --leak-check=full /usr/sbin/nginx -g "daemon off;"
(测试环境使用)分析内存泄漏位置。/etc/security/limits.conf
,增加以下内容(针对Nginx用户):* soft nofile 65535 * hard nofile 65535
编辑/etc/sysctl.conf
,优化TCP参数(减少TIME_WAIT连接占用):net.ipv4.tcp_tw_reuse = 1 # 重用TIME_WAIT连接 net.ipv4.tcp_tw_recycle = 1 # 快速回收TIME_WAIT连接(官方已不建议,可移除) net.ipv4.tcp_max_tw_buckets = 6000 # 最大TIME_WAIT连接数 net.core.somaxconn = 65535 # 监听队列长度 net.ipv4.tcp_max_syn_backlog = 65535 # SYN队列长度
应用配置:sysctl -p
。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
http
块中添加limit_conn
配置,限制每个IP的并发连接数(如每个IP最多20个连接):limit_conn_zone $binary_remote_addr zone=perip:10m; # 定义共享内存区域 server { limit_conn perip 20; # 每个IP最多20个连接 }
proxy_cache off;
(nginx.conf
中)ssl_session_cache
行。nginx -s reload
;强制重启(中断服务):systemctl restart nginx
(仅在紧急时使用)。$upstream_cache_status
)。wrk
或ab
进行压力测试(如wrk -t12 -c400 -d30s http://example.com/
),对比优化前后的内存/ CPU增长曲线;dmesg
或/var/log/messages
,确认无OOM(Out of Memory)事件发生。通过以上步骤,可系统性解决CentOS下Nginx资源占用过高的问题,同时建立长效监控机制,避免问题复发。