
網頁伺服器的效能相關設定
先確認瓶頸在哪
調整伺服器設定之前,先確認問題不是出在應用層。如果純文字頁面的回應時間就已經偏高,那是後端或資料庫的問題,前端調整幫助有限。
排查順序見網站慢的常見原因與優先處理順序。
一、啟用壓縮
Nginx
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_proxied any;
gzip_types
text/plain text/css text/xml
application/javascript application/json
application/xml image/svg+xml;
不要壓縮已壓縮的格式——JPG、PNG、WebP、MP4、ZIP 再壓縮沒有效果,只是浪費 CPU。
關於 Brotli
壓縮率通常優於 gzip,但需要額外的模組。建議兩者並存,讓瀏覽器依支援情況協商。
Apache
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/plain
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
二、靜態檔案的快取標頭
Nginx
location ~* \.(css|js|jpg|jpeg|png|gif|webp|avif|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
搭配檔名雜湊使用時可以設更長。若檔名不變而內容會更新,就不能設太長——這也是為什麼建議更新資源時改檔名。
快取層級的完整說明見快取是什麼。
Apache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 30 days"
ExpiresByType text/css "access plus 30 days"
ExpiresByType application/javascript "access plus 30 days"
</IfModule>
三、HTTP/2 與 HTTP/3
HTTP/2 需要加密連線才能啟用,帶來多工與標頭壓縮的效益。
listen 443 ssl; http2 on;
HTTP/3 基於 QUIC,需要額外的模組或較新的版本支援,並開放 UDP 443:
listen 443 quic reuseport; add_header Alt-Svc 'h3=":443"; ma=86400';
啟用前確認防火牆已開放 UDP 443,否則客戶端會嘗試後回退,反而多一次往返。
四、連線與工作行程
Nginx
worker_processes auto; worker_connections 2048; keepalive_timeout 65; keepalive_requests 1000; sendfile on; tcp_nopush on; tcp_nodelay on;
worker_processes auto 會依 CPU 核心數自動設定,多數情況不需要手動調整。
Apache 的 MPM 選擇
建議使用 event MPM 搭配 PHP-FPM,而非傳統的 prefork + mod_php。
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
MaxRequestWorkers 要依實際記憶體評估——設太高會在流量尖峰時耗盡記憶體,反而更糟。
五、PHP-FPM 的行程池
pm = dynamic pm.max_children = 20 pm.start_servers = 4 pm.min_spare_servers = 2 pm.max_spare_servers = 8 pm.max_requests = 500
怎麼估 max_children
可用記憶體 ÷ 單一 PHP 行程的平均用量
例如可用 2GB、每個行程約 60MB,則約 30 上下。寧可保守,因為超出記憶體會觸發系統的行程終止機制,比排隊等待更糟。
pm.max_requests 設定行程處理一定次數後重啟,可緩解記憶體洩漏累積。
六、上傳與逾時的相關設定
這幾個值需要在多處保持一致,否則會出現難以理解的錯誤。
| 項目 | Nginx | PHP |
|---|---|---|
| 上傳大小 | client_max_body_size | upload_max_filesizepost_max_size |
| 執行時間 | fastcgi_read_timeout | max_execution_time |
只改 PHP 沒有改 Nginx,上傳大檔會得到 413 錯誤;只改 Nginx 沒改 PHP,則會被 PHP 端擋下。
相關錯誤的判讀見Nginx 與 Apache 的疑難排解。
七、反向代理的快取
對變動不頻繁的頁面,可在 Nginx 層做快取:
fastcgi_cache_path /var/cache/nginx levels=1:2
keys_zone=SITE:100m inactive=60m;
location ~ \.php$ {
fastcgi_cache SITE;
fastcgi_cache_valid 200 10m;
fastcgi_cache_bypass $cookie_session;
fastcgi_no_cache $cookie_session;
}
務必排除登入狀態與個人化頁面——否則可能把 A 使用者的頁面快取後回應給 B,這是嚴重的資料外洩事故。
驗收時必測:用兩個帳號分別登入,確認各自看到正確的資料。
調整後要驗證
nginx -t或apachectl configtest- reload 而非 restart
- 用瀏覽器開發者工具確認回應標頭
- 觀察一段時間的記憶體與回應時間
- 用實際的行動網路測試感受
本文的設定範例以常見的環境為例,實際的路徑、模組名稱與指令可能因作業系統、版本與安裝方式而異。套用前請先在測試環境驗證,並確實備份原設定檔。