WPbuy 團購論壇

 找回密碼
 立即註冊

[轉貼] WordPress 配置 Nginx FastCGI 靜態頁面快取及負載測試

[複製鏈接]
yungkeli 發表於 2018-7-10 22:26:54 | 顯示全部樓層 |閱讀模式
Professional DNS
原文出處:https://yungke.me/wordpress-configuring-nginx-fastcgi-cache/

WordPress 的主要性能瓶頸是由處理 PHP 引起的,因此為提高我們網站的性能,我們需要減少 Web 主機處理 PHP 和數據庫的數量。

這個就是為什麼要在 WordPress 加入頁面快取的目的。

頁面快取 (Page Cache)

WordPress 快取方式其中的一種,可參考之前寫的「WordPress 的核心緩存概念」

一些快取外掛都可以達成頁面快取目的,如:WP Rocket / W3 Total Cache / WP Super Cache / Cache Enabler,而我個人偏愛 Nginx FastCGI cache 方式,省去使用一個外掛安裝。

Nginx FastCGI Cache 的工作原理類似 Squid 的快取功能,把 URL 及相關組合當做一個 Key,用 Md5 算法對 Key 進行哈希,得到硬碟上對應的哈希目錄路徑,進而將快取的內容保存在該目錄內。

保存的目錄位置會在 /var/run/nginx-cache 目錄內。

這樣的快取好處:

快取 fastcgi 生成的內容,很多情況是 PHP 生成的動態的內容,少了 Nginx 與 php 的通信的次數,更減輕了 PHP 和數據庫的壓力。

早期大家不愛用 Nginx FastCGI Cache 的快取方式,是因為快取服務只能為指定 URL 或狀態碼設置過期時間,不支持指令手動清除快取,造成很多不便;現在我們可以通過 Nginx 的模組 ngx_cache_purge 來清除指定 URL 的快取,或使用 Nginx Helper 或 Nginx Caching 外掛來實現。

Nginx FastCGI cache 與 Varnish cache

說到 Nginx FastCGI Cache 就不能不提 Varnish 了,Varnish Cache 是備受推崇的 Web 應用程序加速器,利用 HTTP 反向代理,快取任何頁面請求的返回內容,運作方式與 Nginx FastCGI cache 大致上相同。

Varnish 速度真的很快、很快 !

但是我使用 Nginx 系統,並沒有選擇 Varnish cache 作為快取選項,由下面 2 張的運作結構圖,就可以知道我選擇了 Nginx FastCGI Cache 沒有選擇 Varnish 的原因。

Nginx FastCGI Caching and Redis 服務架構


Nginx, Varnish Caching and Redis 服務架構


我的 WordPress 網站已配置 Let’s Encrypt SSL 加密,如果要使用 Varnish 加速,我需要 Nginx 在前面接收 80 與 443 的請求,然後再將它們傳遞給 Varnish 快取,我們可以將 Nginx 用於此目的,但是有必要為了 Varnish 加速快速,增加主機的複雜性,思考是否值得這麼做。

另一方面,在主機的維護上,盡量可以簡單性、穩定性去建置,即使出了錯誤,也能很快速的找出問題所在。

在 Nginx 中啟用 FastCGI Cache

如果您使用 EasyEngine 或 Webinoly LNMP 安裝包建置 Linux 系統,啟用 Nginx FastCGI cache 是一件很容易的事,執行以下的指令和啟用外掛,這樣就可以了。

EasyEngine
  1. ee site create example.com --wpfc #wordpress + nginx fastcgi_cache
複製代碼


Webinoly
  1. sudo site domain.com -wp -cache #wordpress + nginx fastcgi_cache + redis
複製代碼


PS. Webinoly 在 1.5.0 版本中,把 redis (Object cache) 也加入了 wordpress 快取配置中。

在 WordPress 中啟動清除快取外掛

然後在 wordpress 控制台,將 Nginx Helper 和 Redis Object Cache 外掛都啟動。

Nginx Helper 設置:




Redis Object Cache 設置:


配置 Nginx 以啟用 Nginx fastcgi cache

如果您是自己建置 LNMP 系統 (不是 EasyEngine 或 Webinoly 系統),若要啟用 Nginx fastcgi cache 功能,我們需要對 Nginx 服務器配置進行一些更改。

以當前默認的虛擬主機文件為例:

  1. vi /etc/nginx/sites-available/default
複製代碼


配置文件範例:

  1. fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
  2. fastcgi_cache_key "$scheme$request_method$host$request_uri";
  3. fastcgi_cache_use_stale error timeout invalid_header http_500;
  4. fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
複製代碼


快取的位置 (/var/run/nginx-cache) 可以設置硬碟上的任何資料夾,建議在 Ubuntu 中選擇 /var/run 文件夾,因為它是作為 tmpfs 的掛載的,從記憶體中讀取快取。

跳過 Nginx 不快取某些頁面:

  1. set $skip_cache 0;
  2. # POST requests and urls with a query string should always go to PHP
  3. if ($request_method = POST) {
  4.     set $skip_cache 1;
  5. }
  6. if ($query_string != "") {
  7.     set $skip_cache 1;
  8. }   
  9. # Don't cache uris containing the following segments
  10. if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
  11.     set $skip_cache 1;
  12. }  
  13. # Don't use the cache for logged in users or recent commenters
  14. if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
  15.     set $skip_cache 1;
  16. }
複製代碼


PHP 配置中輸入以下參數:

  1. fastcgi_cache_bypass $skip_cache;
  2. fastcgi_no_cache $skip_cache;
  3. fastcgi_cache WORDPRESS;
  4. fastcgi_cache_valid 60m;
  5. add_header X-FastCGI-Cache $upstream_cache_status;
複製代碼


add_header 參數是為服務器響應添加了一個額外的標頭,方便我們可以檢查確定是否從快取中提供請求。

完整的 Nginx conf 的配置如下:

  1. fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
  2. fastcgi_cache_key "$scheme$request_method$host$request_uri";
  3. fastcgi_cache_use_stale error timeout invalid_header http_500;
  4. fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

  5. server {
  6.     listen 80;
  7. listen [::]:80;

  8. server_name example.com;

  9. root /var/www/example.com/htdocs;
  10. index  index.php index.html index.htm;

  11. set $skip_cache 0;

  12. if ($request_method = POST) {
  13.     set $skip_cache 1;
  14.     }

  15. if ($query_string != "") {
  16.     set $skip_cache 1;
  17.     }

  18. if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
  19.     set $skip_cache 1;
  20.     }

  21. if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
  22.     set $skip_cache 1;
  23.     }

  24. location ~ \.php$ {
  25.     try_files $uri =404;
  26.     include fastcgi_params;
  27.     fastcgi_pass php;
  28.     fastcgi_cache_bypass $skip_cache;
  29.     fastcgi_no_cache $skip_cache;
  30.     fastcgi_cache WORDPRESS;
  31.     fastcgi_cache_valid 60m;
  32.     add_header X-FastCGI-Cache $upstream_cache_status;
  33.     }

  34. location ~ /\. {
  35. deny all;
  36. access_log off;
  37. log_not_found off;
  38.     }

  39. location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
  40.     expires 30d;
  41.     access_log off;
  42.     }

  43. location ~ .*\.(js|css)?$ {
  44.     expires 30d;
  45.     access_log off;
  46.     }
  47. }
複製代碼


保存並退出文件後,請檢查 Nginx 配置文件是否語法錯誤:

  1. sudo nginx -t
複製代碼


假設一切正常,請重啟 Nginx

  1. sudo service nginx restart
複製代碼
請會員多利用「廣播」功能,查詢最新佈景和外掛動態   
 樓主| yungkeli 發表於 2018-7-10 22:35:00 | 顯示全部樓層
承接樓上

驗證 Nginx fastcgi cache 是否正常工作

利用 Chrome F12 來檢查 header 返回值



  • HIT – 正確的 Nginx fastcgi cache 返回值
  • MISS – 頁面未快取並由 PHP-FPM 返回值 (可重複刷新頁面,查看返回值為 HIT 或 BYPASS)
  • BYPASS – 頁面已快取但是沒有提供快取版本。當它是我們指定繞過快取的頁面 (例如:管理頁面) 或用戶登錄時,會發生這種情況。


負載測試

使用 Linode 2G RAM 方案的 VPS 來做開啟 Nginx fastcgi cache 測試。

我們利用 Loader.io 免費方案 (10,000 clients / 1 min test)

選擇第 2 個測試項目持續 1 分鐘,每秒鐘 1000 個用戶。(每分鐘 60000 個訪問者),Loader.io 有 3 種測試方法,請見 Test Types 說明。

我們先使用一個沒有做快取的測試網站 (load.yungke.me),首頁有 10 篇帶有圖片的文章。





結果不易外,測試一開始沒幾秒,網站就已經打不開了,出現大量 Timeout 的錯誤。

再來,測試網頁為 yungke.me,使用 Nginx fastcgi cache (頁面快取) + Redis Object Cache,一樣選擇第 2 個測試項目持續 1 分鐘,每秒鐘 1000 個用戶。(每分鐘 60000 個訪問者)





啟用 Nginx fastcgi cache 快取後,每秒 1000 個用戶,持續 1 分鐘,我們可以看到平均響應時間在 3936ms 上下,但是沒有錯誤率。

結語

以一個 2G RAM VPS 來說,開啟了 Nginx fastcgi cache + Redis 後的表現,是令我們所滿意的。

利用 Nginx 本身的輕量功能,再搭配 Redis Object Cache 對象快取,可建置一個低負載的網站,也可以這麼說:可以在主機後端做的工作,就不要推到網站前端來做。

2018/07/09 補充:

Redis 快取設置:

Redis 安裝後或使用 EE 及 Webinoly 安裝,Redis 的預設值是沒有限制快取的大小及快取計畫,需修改 /etc/redis/redis.conf 文件,符合我們的需求。

  1. vi /etc/redis/redis.conf
複製代碼


取消掉 maxmemory 前面的 # 號,修改如下:

  1. maxmemory 128000000
複製代碼


預設的快取計畫,取消掉 maxmemory-policy noeviction 前面的 # 號,修改如下

  1. maxmemory-policy allkeys-lru
複製代碼


保存文件後,重啟 Redis 服務。

  1. sudo service redis-server restart
  2. sudo service php7.0-fpm restart #或 php7.2-fpm
複製代碼


參考資料:

請會員多利用「廣播」功能,查詢最新佈景和外掛動態   
 樓主| yungkeli 發表於 2018-7-10 22:52:32 | 顯示全部樓層
這一篇真的很長,看不完沒關係。

有關於 WordPress 快取的問題,都可提出。

只要我會的,都會回覆您。
請會員多利用「廣播」功能,查詢最新佈景和外掛動態   
qouwso 發表於 2018-7-13 17:57:15 | 顯示全部樓層
請問同一台VPS有多個網站使用 Nginx fastcgi cache + Redis 會有什麼副作用嗎?
 樓主| yungkeli 發表於 2018-7-13 20:24:03 | 顯示全部樓層
我目前在同一台主機有 4 個網站是 Nginx fastcgi cache + Redis
並沒有發現有甚麼錯誤。

Redis 要注意的是在 wp-config.php 文件中設置 wp_cache_key_salt 或資料表前輟是唯一名稱,避免快取錯誤。
請會員多利用「廣播」功能,查詢最新佈景和外掛動態   
您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

PhotonVPS

服務信箱|推廣註冊|手機版|WPbuy 團購論壇 |網站地圖

GMT+8, 2018-12-12 13:46 , Processed in 0.012888 second(s), 32 queries , Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表