打造噴射機級速度的 WordPress:Nginx FastCGI Cache 全攻略 (含預熱腳本與 404 報錯排除)

前言:為什麼你的 WordPress 需要伺服器級快取?

在 1GB RAM 的小資型伺服器(如 AWS EC2 t3.micro)跑 WordPress,最常遇到的問題就是 PHP-FPM 與 MySQL 佔用過多資源,導致網頁載入緩慢。雖然快取外掛(如 WP Rocket)很方便,但最強大的優化其實是在 Nginx 層級。透過Nginx FastCGI Cache,Nginx 會將 PHP 產生的 HTML 直接存入 SSD。當訪客進入時,Nginx 直接發貨,完全跳過 PHP 運算,讓你的網站達成「毫秒級」開啟。

但這有一個致命弱點:沒人點過的頁面,就不會有快取。 導致第一位訪客(或 Google 爬蟲)進來時依然覺得慢。今天這篇文章將帶你從底層設定開始,一路配置到「首點即秒開」的自動化預熱系統。


第一階段:全局配置 (The Foundation)

首先,我們需要在 Nginx 的主設定檔中定義快取的「倉庫位置」與「規則」。

修改檔案: /etc/nginx/nginx.conf (或 /etc/nginx/conf.d/cache.conf) 放置位置: 放在 http { ... } 區塊內。

# 定義快取路徑與參數
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:50m inactive=24h max_size=1g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

參數深度解析:如何根據伺服器調整?

參數 說明 1GB RAM 建議 4GB+ RAM 建議
levels=1:2 目錄層級。防止單一目錄檔案過多導致讀取變慢。 保持預設 保持預設
keys_zone 記憶體中的金鑰區。10MB 可存 8 萬個網址。 10m - 50m 100m+
inactive 閒置清理。多久無人存取就刪除快取檔案。 24h 24h
max_size 硬碟上限。防止快取把硬碟塞爆。 1g 5g+

第二階段:站點邏輯設定 (The Logic)

接著,我們要告訴 Nginx:哪些頁面要快取,哪些(如後台、登入者)絕對不能快取。

修改檔案: /etc/nginx/sites-available/your-site.conf 放置位置: server { ... } 區塊內,必須在 location ~ \.php$ { ... } 之前

# 預設不跳過快取
set $skip_cache 0;

# POST 請求、帶有參數的網址不快取
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }

# 登入者、評論者或剛發布評論的訪客不快取 (避免看到舊內容)
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
}

# 特定頁面排除快取 (如 Sitemap)
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
    set $skip_cache 1;
}

第三階段:聰明地獲取全站地圖 — Yoast SEO

打好底層後,我們需要一張「自動化地圖」來引導預熱。請讀者先行安裝 WordPress 知名外掛 Yoast SEO

啟用後,它會自動生成 https://yourdomain.com/sitemap_index.xml這是一個關鍵點:Yoast 生成的地圖是「虛擬檔案」,硬碟裡找不到它。這會導致下一個常見的「坑」。

第四階段:避坑指南 — 修復 Sitemap 404 陷阱

很多讀者設定完前兩步後,會發現網站地圖在瀏覽器可以正常打開,但是用命令列打不開,這會造成我們等等要用的腳本無法得到正確的sitemap_index.xml檔案,進而導致快取失敗。

如何檢測?

在命令列輸入:

curl -I https://yourdomain.com/sitemap_index.xml

如果你看到 HTTP/2 404 Not Found,代表 Nginx 誤把這個虛擬地圖當成實體檔案處理了。在這樣的情況下,等等我們自制的爬蟲快取程式會找不到你的sitemap_index.xml檔案而導致快取失敗

解決方案

先找到你的網站設定檔,通常都在 /etc/nginx/sites-available/ 下。在你的靜態資源 location 區塊中,確保清單裡沒有 xml

sudo vi /etc/nginx/sites-available/your.website.conf

location ~* ^.+\.(js|css|jpg|jpeg|gif|png|ico|zip|tgz|gz)$ {

    #js|css|jpg|jpeg|gif|png|ico|zip|tgz|gz 這一串裡不能有xml

    expires 30d;
    access_log off;
    # 找不到這些副檔名的實體檔案時,直接報404錯誤,以免被惡意爬蟲攻擊
    try_files $uri =404;
}

修改後重載 Nginx:sudo nginx -s reload。再次 curl -I 看到 200 OK 才是成功避坑。

如果要再進一步針對sitemap設定,讓nginx知道如何處理它,可以在所有location區塊之前加上下面這些設定,確保針對xml檔案的特殊處理被優先考慮,要把這段放在所有location區塊之前是因為Nginx 會由上而下匹配正則表達式,放在後面就會因為被其他規則蓋過去而失去作用了。

location ~* \.xml$ {
    try_files $uri $uri/ /index.php?$args;
    expires off;
    add_header Cache-Control "no-cache, no-store, must-revalidate, max-age=0";
    # 確保不被 FastCGI 快取住地圖
    fastcgi_cache_bypass 1;
    fastcgi_no_cache 1;
}

這些設定的好處是當google爬蟲來抓取你的文章時,總是能”看到”最新的文章列表

第五階段:實現「首刷即 HIT」— 自動化預熱系統

萬事具備,現在派出「補貨機器人」。這個腳本會模擬真實 Chrome 瀏覽器,發送完整的 GET 請求,確保 Nginx 產生的快取指紋與真人完全一致。

像我這種個人的小網站,我就把這個腳本放在自己的家目錄裡

vi ~/warmup.sh
#!/bin/bash
SITEMAP_INDEX="https://yourdomain.com/sitemap_index.xml"
USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
ACCEPT_ENCODING="gzip, deflate, br"

echo "=== 🚀 正在啟動全站預熱系統 ==="

MAPS=$(curl -s -L -A "$USER_AGENT" "$SITEMAP_INDEX" | grep -oP '(?<=<loc>)[^<]+')

for map in $MAPS; do
    echo "📂 處理子地圖: $map"
    URLS=$(curl -s -L -A "$USER_AGENT" "$map" | grep -oP '(?<=<loc>)[^<]+' | grep -v '\.xml')
    for url in $URLS; do
        echo -n "⚡ 預熱中: $url ... "
        # 模擬 GET 請求以產生完整快取
        STATUS=$(curl -L -s -o /dev/null -D - -A "$USER_AGENT" \
            -H "Accept-Encoding: $ACCEPT_ENCODING" \
            "$url" | grep -i "x-fastcgi-cache" | awk '{print $2}' | tr -d '\r')
        echo "[$STATUS]"
    done
done
echo "=== ✅ 全站預熱完成 ==="

存檔後別忘了加上可執行的權限

chmod +x ~/warmup.sh

如果成功了,會看到類似下面的執行畫面:

第六階段:自動維運 (Crontab)

最後,我們讓它每天定時補貨。建議頻率為 「每天凌晨 3:00」,這能確保每天早晨的第一批讀者都能享受秒開體驗。

輸入 crontab -e 並加入以下排程。

⚠️ 避坑小提醒: crontab 在背景執行時的環境變數非常少,請**務必使用「絕對路徑」**來指定你的 bash 與腳本位置,千萬不要用 ~/,否則排程極有可能會失效!

0 3 * * * /bin/bash /your/path/warmup.sh > /your/path/warmup.log 2>&1

結語

透過這六個階段的配置,你已經在 1GB RAM 的小主機上實現了負載優化。這套「底層配置 + 地圖引導 + 自動預熱」的架構,能讓你的 WordPress 在面對高流量時依然穩定如山。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料