Nginx + PHP-FPM 的高效能設定
在現代網頁伺服器架構中,Nginx 搭配 PHP-FPM 是最經典且高效能的組合。Nginx 以其非同步、事件驅動的特性處理靜態資源與反向代理,而 PHP-FPM(FastCGI Process Manager)則負責動態內容的執行。對於中階 Linux 使用者而言,預設安裝往往只是起點,透過微調核心參數與 PHP-FPM 設定,才能釋放這兩者的真正潛力。本文將引導您在 Ubuntu 22.04 或 Debian 12 環境下,完成一套高並發、低延遲的效能優化設定。
第一步:基礎環境安裝
首先,請確保您的系統已更新,並安裝必要的套件。在 Debian/Ubuntu 系列發行版中,PHP-FPM 通常作為獨立套件提供。
sudo apt update
sudo apt install nginx php-fpm php-cli php-mysql php-mbstring php-xml php-gd -y
安裝完成後,啟動並啟用 Nginx 與 PHP-FPM 服務:
sudo systemctl enable --now nginx
sudo systemctl enable --now php8.1-fpm
註:請根據實際安裝的 PHP 版本調整服務名稱,例如 php8.2-fpm 或 php8.3-fpm。
第二步:Nginx 核心效能優化
Nginx 的效能關鍵在於worker processes 的數量與文件描述符的限制。
-
調整 Worker Processes 打開 Nginx 主設定檔
/etc/nginx/nginx.conf。將worker_processes設為auto,這會自動偵測 CPU 核心數。若您的伺服器僅運行 Nginx,可手動指定為 CPU 核心數。worker_processes auto; worker_rlimit_nofile 65535; -
啟用事件驅動模型 在
events區塊中,確保使用epoll並提高連接數限制。這對於高併發場景至關重要。events { worker_connections 4096; use epoll; multi_accept on; } -
全域快取與壓縮 在
http區塊中,建議啟用 gzip 壓縮並設定瀏覽器快取頭,減少頻寬消耗。gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
第三步:PHP-FPM 進階調校
PHP-FPM 的設定檔位於 /etc/php/8.1/fpm/pool.d/www.conf(路徑依版本可能不同)。這裡是效能瓶頸的高發區。
-
調整 PM 模式 對於高流量伺服器,預設的
dynamic模式通常足夠,但需調整參數。若記憶體有限,可考慮ondemand。pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35計算邏輯:
pm.max_children應根據伺服器記憶體除以每個 PHP-FPM 進程的平均記憶體佔用(可用ps命令觀察)來決定,避免 OOM(記憶體不足)錯誤。 -
提升文件描述符限制 在
[www]區塊上方添加或修改以下參數,確保 PHP-FPM 能開啟足夠的檔案連接:pm.max_requests = 500 request_terminate_timeout = 120pm.max_requests設定每個子進程處理完 500 個請求後自動重啟,有助於釋放記憶體碎片,保持長期運行的穩定性。 -
啟用 OPCache 編輯
/etc/php/8.1/fpm/php.ini並確保 OPCache 已啟用且配置合理:opcache.enable=1 opcache.memory_consumption=256 opcache.max_accelerated_files=10000 opcache.revalidate_freq=60OPCache 將 PHP 編譯後的字碼快取在記憶體中,可大幅降低 CPU 負載。
第四步:系統層級優化
除了應用層設定,Linux 核心參數也影響網路效能。編輯 /etc/sysctl.conf 並加入以下內容:
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
套用設定:
sudo sysctl -p
最後,重新啟動所有服務以套用變更:
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
常見問題與排除
Q1: Nginx 回報 502 Bad Gateway 錯誤?
這通常意味著 Nginx 無法連接到 PHP-FPM 的 Unix socket。請檢查 /etc/php/8.1/fpm/pool.d/www.conf 中的 listen 參數路徑是否與 Nginx 虛擬主機設定中的 fastcgi_pass 一致。同時確認 socket 檔案權限,確保 Nginx 使用者(通常是 www-data)有讀寫權限。
Q2: PHP-FPM 進程數過多導致記憶體耗盡?
若伺服器出現 OOM Killer 動作,請降低 pm.max_children。您可以透過 htop 觀察 PHP-FPM 進程的平均 RSS 記憶體使用量。例如,若平均每個進程佔用 50MB,而伺服器有 1GB 可用記憶體給 PHP,則 pm.max_children 不應超過 20。
小結
透過上述步驟,我們不僅完成了 Nginx 與 PHP-FPM 的基礎架設,更從事件驅動模型、進程管理、記憶體快取到核心網路參數進行了全方位優化。這些設定能顯著提升伺服器在高併發下的回應速度與穩定性。請記住,最佳化是一個持續的過程,建議定期使用 nginx -t 測試設定語法,並透過監控工具觀察實際資源使用情況,以進行更精細的微調。