Nginx 搭配 PHP-FPM 是現代 PHP 高效能部署的標準架構。本文涵蓋 FastCGI 原理、PHP-FPM 編譯安裝、Nginx 整合配置、關鍵參數調優與壓測驗證,適合生產環境參考。
Nginx 本身不解析 PHP,而是將請求透過 FastCGI 協議轉發給 PHP-FPM 進程管理器:
.php 頁面location ~ \.php$ 匹配,轉發至 127.0.0.1:9000 (或 Unix Socket)
# 1. 安裝依賴
yum install -y gcc gcc-c++ libxml2 libxml2-devel openssl openssl-devel \
libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel \
freetype freetype-devel zlib zlib-devel
# 2. 下載原始碼
wget https://www.php.net/distributions/php-8.2.10.tar.gz
tar zxvf php-8.2.10.tar.gz
cd php-8.2.10
# 3. 配置編譯選項 (含 FPM)
./configure --prefix=/usr/local/php \
--enable-fpm \
--with-fpm-user=www \
--with-fpm-group=www \
--with-openssl \
--with-curl \
--with-zlib \
--enable-mbstring \
--with-pdo-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--enable-bcmath \
--enable-sockets \
--enable-opcache
# 4. 編譯安裝
make -j$(nproc) && make install
# 5. 複製配置檔
cp php.ini-production /usr/local/php/lib/php.ini
cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf
cp sapi/fpm/www.conf /usr/local/php/etc/php-fpm.d/www.conf
編輯 /usr/local/php/etc/php-fpm.d/www.conf:
; 進程管理模式:dynamic (動態) / static (靜態) / ondemand (按需)
pm = dynamic
; 最大子進程數 (視記憶體而定:4GB 建議 100~200)
pm.max_children = 100
; 啟動時進程數
pm.start_servers = 10
; 最小閒置進程數
pm.min_spare_servers = 5
; 最大閒置進程數
pm.max_spare_servers = 20
; 每個進程處理請求數上限 (防止記憶體洩漏)
pm.max_requests = 1000
; 請求超時 (秒)
request_terminate_timeout = 60
; 慢日誌閾值 (秒)
request_slowlog_timeout = 5
slowlog = /usr/local/php/var/log/slow.log
; 監聽方式:Unix Socket 效能優於 TCP
listen = /tmp/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 快取優化
fastcgi_cache php_cache;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 404 1m;
}
# 靜態資源快取
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
在 http 區塊加入:
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=php_cache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# 建立測試頁
echo ' /var/www/html/phpinfo.php
# 瀏覽器訪問確認
curl -I https://example.com/phpinfo.php
# 壓測 (wrk 範例)
wrk -t4 -c200 -d30s https://example.com/phpinfo.php
| 現象 | 可能原因 | 解決方向 |
|---|---|---|
| 502 Bad Gateway | PHP-FPM 未啟動 / Socket 路徑錯誤 / 權限不足 | 檢查服務狀態、Socket 權限、Nginx error.log |
| 504 Gateway Timeout | 腳本執行超過 request_terminate_timeout | 優化慢查詢、調大超時或異步處理 |
| 檔案上傳失敗 | client_max_body_size / upload_max_filesize 過小 | 同步調整 Nginx、PHP 兩側限制 |