在采取优化措施前,需先精准定位内存占用问题,避免盲目调整:
top命令(按M键按内存排序)或ps -o pid,rss,command -p $(pgrep nginx)命令,查看Nginx worker进程的实际物理内存(RSS)占用情况,确认是否为单个进程持续增长或所有进程均占用过高。pmap -x $(pgrep nginx | head -n1)命令,查看具体进程的内存映射,识别共享内存(SHM)或缓存占用是否异常。/var/log/nginx/error.log),搜索“memory”“oom”等关键词,判断是否因内存泄漏(如进程频繁重启、内存持续增长)或配置错误导致。worker_processes参数建议设置为CPU核心数(auto可自动匹配),过多的worker进程会竞争内存资源。修改/etc/nginx/nginx.conf文件:worker_processes auto; # 根据CPU核心数自动调整 worker_rlimit_nofile限制每个worker进程的最大文件描述符(间接控制内存),或在支持的情况下使用worker_rlimit_memory(需第三方模块)限制内存。例如:worker_rlimit_nofile 65535; # 每个worker最多6.5万个文件描述符 worker_connections),避免单个进程占用过多内存。在events块中设置:events { worker_connections 1024; # 每个worker最多1024个连接 } 修改后需测试配置语法(nginx -t)并重载(systemctl reload nginx)。静态资源(如图片、CSS、JS)的处理是Nginx内存占用的主要来源之一,需通过缓存与缓冲区设置减少内存消耗:
expires指令设置浏览器缓存,减少重复请求;禁用访问日志(access_log off)降低IO开销。例如:location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { sendfile on; # 启用高效文件传输 tcp_nopush on; # 优化数据包发送 expires 7d; # 浏览器缓存7天 access_log off; # 关闭访问日志 add_header Cache-Control "public"; # 公开缓存 } client_body_buffer_size)、请求头(large_client_header_buffers)和代理缓冲区(proxy_buffers)的大小,避免大请求占用过多内存。例如:client_body_buffer_size 8k; # 客户端请求体缓冲区设为8KB large_client_header_buffers 4 8k; # 请求头缓冲区设为4个8KB proxy_buffers 4 16k; # 代理缓冲区设为4个16KB proxy_buffer_size 16k; # 代理缓冲区大小设为16KB 这些参数需根据实际业务调整(如上传文件大小需匹配client_max_body_size)。HTTPS流量的SSL会话缓存配置不当会导致内存占用过高,需调整缓存大小与超时时间:
ssl_session_cache shared:SSL:20m; # 共享SSL会话缓存设为20MB ssl_session_timeout 10m; # 会话超时时间设为10分钟 ssl_session_tickets off; # 关闭会话票证(可选,减少内存占用) 修改后需重启Nginx使配置生效。
当物理内存不足时,Swap分区可作为临时缓冲,避免进程被OOM Killer杀死:
sudo fallocate -l 8G /swapfile # 创建8GB空文件 sudo chmod 600 /swapfile # 设置权限 sudo mkswap /swapfile # 格式化为Swap sudo swapon /swapfile # 启用Swap /etc/fstab文件中:echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab vm.swappiness控制系统使用Swap的倾向(0-100,值越小越倾向于使用物理内存)。建议设置为10-30:echo 10 | sudo tee /proc/sys/vm/swappiness # 临时生效 echo 'vm.swappiness = 10' | sudo tee -a /etc/sysctl.conf # 永久生效 sudo sysctl -p # 应用配置 注意:Swap会降低性能,仅作为应急手段,需结合内存优化措施使用。通过cgroups限制Nginx进程组的最大内存使用,避免单个进程占用过多内存导致系统崩溃:
sudo cgcreate -g memory:/nginx echo 1G | sudo tee /sys/fs/cgroup/memory/nginx/memory.limit_in_bytes sudo cgclassify -g memory:nginx $(pgrep nginx) 此方法需root权限,适用于需要严格限制内存的场景。若内存占用持续增长且不释放,需排查内存泄漏问题:
/etc/nginx/nginx.conf中的error_log级别为debug,获取详细内存分配信息(注意:调试日志会显著增加IO负载,仅用于排查):error_log /var/log/nginx/error.log debug; valgrind工具检测内存泄漏(需在测试环境使用,避免影响生产):valgrind --leak-check=full --show-leak-kinds=all /usr/sbin/nginx -g "daemon off;" nginx.conf中的第三方模块(如ngx_http_lua_module),重启Nginx后观察内存占用是否下降,定位问题模块。若Nginx已因内存过高导致服务中断,需立即采取以下措施:
limit_conn模块限制每个IP的并发连接数,减轻服务器负载:limit_conn_zone $binary_remote_addr zone=perip:10m; # 定义共享内存区域 server { location / { limit_conn perip 20; # 每个IP最多20个并发连接 } } proxy_cache off;)或SSL会话缓存(注释ssl_session_cache行),减少内存占用。nginx -s reload)释放内存,若无效则强制重启(systemctl restart nginx)。建立长效监控机制,及时发现内存异常:
Prometheus + Grafana或Zabbix监控Nginx的内存使用率、worker进程数量、缓存命中率等指标,设置告警阈值(如内存占用超过80%时触发告警)。通过以上步骤,可系统性解决Ubuntu环境下Nginx内存占用过高的问题,提升服务器稳定性与性能。需根据实际业务场景调整参数,避免过度优化影响正常服务。