這裡介紹如何設定 Nginx 的 FastCGI 快取功能,加速 WordPress 網頁載入速度。

WordPress 是現在很流行的網站架構,它是以 PHP 語言所開發的 CMS,在使用者每一次瀏覽網頁時,都需要執行 PHP 的程式碼,產生使用者所要求的頁面,這樣的好處是可以動態產生最新的網頁內容,而缺點就是速度會比一般靜態網頁還慢很多。

如果我們的 WordPress 網站只是提供使用者單純瀏覽資料(不需要帳號登入),而網站內容的更新速度也不是非常快,那就可以考慮使用快取的功能,減少 PHP 程式的執行頻率,可以大幅增加網站的載入速度。

Nginx 設定 FastCGI Cache

網頁伺服器設定快取的方法有很多種,若在 Nginx 伺服器中我們可以使用 FastCGI 內建的快取(cache)功能,將 PHP 產生的網頁儲存下來放在快取中,若後來又有相同的網頁請求,就可以直接送出上一次計算的結果,減少 PHP 程式執行的次數。

建立快取存檔案放目錄

首先建立 FastCGI 放置快取檔案的目錄,這個目錄要放在哪裡都可以,自己選擇一個適當的地方即可,只不過目錄的擁有者要設定為 Nginx 的執行帳號(例如 nginx):

sudo mkdir -p /var/cache/nginx/fastcgi
chown -R nginx:nginx /var/cache/nginx

啟用 FastCGI Cache 快取功能

修改 /etc/nginx/nginx.conf 設定檔,在 http 區塊中(要在 server 區塊之外)加入以下設定:

http {
  # [略]

  fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=GTWANG_CACHE:16m inactive=60m max_size=256m;
  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;

  # [略]
}

這裡比較重要的設定是 fastcgi_cache_path,後面接的路徑就是剛剛建立好的快取目錄,未來 FastCGI 會將網頁的快取檔案放在此目錄之下。

keys_zone 則是用來指定存放的鍵值的空間與使用的記憶體大小,1 MB 的記憶體大約可以存放八千個左右的鍵值,也就是說若設定為 16 MB 的話(16m),大約可以快取 128,000 個左右的網址,這個值請根據自己的網佔有多少 PHP 網址來調整。

inactive 是設定當檔案經過多沒有使用,就從快取中移除,這裡是設定 60 分鐘(60m)。

max_size 是設定快取檔案的總容量上限(也就是放在 /var/cache/nginx/fastcgi 中的檔案大小上限),這個也是會跟網站的規模與內容有關,另外亦須考慮硬碟空間。若檔案大小超過這個上限值的時候,會從最久沒用的快取檔案開始刪除。

關於其餘的參數說明,請參考 Nginx 的文件

設定 PHP 的快取規則

在個別網站的 server 區塊,加入以下的 FastCGI 快取設定,讓普通的 WordPress 網頁可以使用快取功能,排除一些不適合快取的網址:

server {
  # [略]

  set $skip_cache 0;

  # POST 請求不用快取
  if ($request_method = POST) {
      set $skip_cache 1;
  }

  # 若有 query 參數的網址不用快取
  if ($query_string != "") {
      set $skip_cache 1;
  }

  # 特殊的網址不用快取
  if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
      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;
  }

  # 加入快取資訊表頭(除錯用)
  add_header X-Cache $upstream_cache_status;

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

    # FastCGI 快取設定
    fastcgi_cache GTWANG_CACHE;
    fastcgi_cache_valid 200 60m;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    if (!-f $document_root$fastcgi_script_name) {
      return 404;
    }
  }

  # [略]
}

由於這裡的設定比較複雜,修完成後,建議先讓 Nginx 自動檢查一下設定檔是否有問題:

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

若設定檔測試無誤,則重新啟動 Nginx 伺服器:

systemctl restart nginx

這樣就完成 FastCGI 快取的設定的。

之後我們可以觀察看看 /var/cache/nginx/fastcgi 目錄下快取檔案的狀況,檢查是否有建立快取檔案,以及整個目錄的大小與檔案數量是否容易超過上限值等。

查看 X-Cache 網頁標頭

由於我們在設定檔中有設定讓網頁加入 X-Cache 這個標頭,它會標示目前的網頁是否是從快取產生的,若為 HIT 則代表從快取產生,而若為 MISS 則代表由正常的 PHP 所產生,若為 BYPASS 則代表該網址不適用快取(被我們設定排除,例如 WordPress 管理頁面)。我們可以開啟自己的網頁,使用瀏覽器的開發人員工具,查看這個標頭欄位:

網頁 X-Cache 標頭

RAM Disk

使用 ram disk 來儲存快取檔案可以讓效能更好。在 /etc/fstab 中加入這一行,即可讓系統開機自動掛載 ram disk:

tmpfs /var/cache/nginx/fastcgi tmpfs defaults,size=256M 0 0

修改好設定之後,若要立即掛載,可執行:

mount -a

查看掛載狀況:

df -ah | grep cache

參考資料:RyadelDigitalOcean 的文件米饭粑WordPress 官方網站LinuxAdmin.ioScaleScale