在采取優化措施前,需先精準定位內存占用問題,避免盲目調整:
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內存占用過高的問題,提升服務器穩定性與性能。需根據實際業務場景調整參數,避免過度優化影響正常服務。