跳至主要內容
問題與解答
網頁伺服器的效能相關設定

網頁伺服器的效能相關設定

問:
gzip 要怎麼設定? PHP-FPM 的 max_children 要設多少? 上傳大檔案出現 413 錯誤 Nginx 可以做頁面快取嗎?
答:

先確認瓶頸在哪

調整伺服器設定之前,先確認問題不是出在應用層。如果純文字頁面的回應時間就已經偏高,那是後端或資料庫的問題,前端調整幫助有限。

排查順序見網站慢的常見原因與優先處理順序

一、啟用壓縮

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 設定行程處理一定次數後重啟,可緩解記憶體洩漏累積。

六、上傳與逾時的相關設定

這幾個值需要在多處保持一致,否則會出現難以理解的錯誤。

項目NginxPHP
上傳大小client_max_body_sizeupload_max_filesize
post_max_size
執行時間fastcgi_read_timeoutmax_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,這是嚴重的資料外洩事故。

驗收時必測:用兩個帳號分別登入,確認各自看到正確的資料。

調整後要驗證

  1. nginx -tapachectl configtest
  2. reload 而非 restart
  3. 用瀏覽器開發者工具確認回應標頭
  4. 觀察一段時間的記憶體與回應時間
  5. 用實際的行動網路測試感受

本文的設定範例以常見的環境為例,實際的路徑、模組名稱與指令可能因作業系統、版本與安裝方式而異。套用前請先在測試環境驗證,並確實備份原設定檔。

發表於2026-08-05   更新於2026-08-20
免費諮詢 · 1 個工作天內回覆

準備好讓網站 開始幫你帶生意了嗎?

不論是要做新網站、救舊網站,還是只想先聊聊方向——先諮詢,不用先付錢,我們照實給你建議。

1 個工作天回覆免費諮詢與報價費用白紙黑字26 年找得到人
免費諮詢
免費諮詢 LINE諮詢 03-4681000 臉書傳訊
免費諮詢 LINE諮詢 03-4681000 臉書傳訊
免費諮詢
免費諮詢 LINE諮詢 03-4681000 臉書傳訊
免費諮詢 LINE諮詢 03-4681000 臉書傳訊