布丁快跑

Nginx 启用 FastCGI_Cache 静态化缓存加速 WordPress 网站博客

2019 年开始启用 Nginx FastCGI_Cache 静态化缓存加速 WordPress,配合 Memcached 缓存减少数据库查询,效果还不错。折腾时注意 FastCGI_Cache 可能会把评论者信息和登陆信息缓存,上线前 WordPress 主题一定要测试适配好。

「Nginx 启用 FastCGI_Cache 静态化缓存加速 WordPress 网站博客:https://bdkp.net/19」

Nginx FastCGI_Cache 简介

使用 Memcached 数据库缓存,主题做好缓存,数据库查询可以大大减少,一定程度上减少服务器压力,提点速度。

为啥还要用 FastCGI_Cache?FastCGI_Cache 是啥?FastCGI_Cache 有什么作用?

「Nginx 启用 FastCGI_Cache 静态化缓存加速 WordPress 网站博客:https://bdkp.net/19」

FastCGI_Cache:缓存 fastcgi 生成的内容「很多情况其实就是静态化 php 生成的动态内容」,可有效减少 nginx 与 php 通信次数,减轻 php 和数据库 mysql 压力,加上 Memcached 缓存数据库查询,效果很不错。

Redis 会与 FastCGI_Cache 一样把评论者信息和登陆信息缓存,需要修改 WordPress 主题适配

Nginx 内置 FastCGI_Cache 缓存,启用即可,但是不支持自动清除缓存。在 WordPress 新建/修改文章,或者访客提交评论,都不会自动清空相关缓存!解决方法:Nginx 安装 ngx_cache_purg 扩展 + WordPress 缓存清理插件 Nginx Helper 即可。

「Nginx 启用 FastCGI_Cache 静态化缓存加速 WordPress 网站博客:https://bdkp.net/19」

编译安装 ngx_cache_purge 模块

有些环境可能已经安装 ngx_cache_purg 模块,如果没有,编译安装上即可,不难。

检查是否已安装 ngx_cache_purge

nginx -V 2>&1 | grep -o ngx_cache_purge

一般都不会安装,如果显示 ngx_cache_purge 则已安装。

编译安装 nginx_cache_purge 扩展

两种方法:一是基于 OneinStack 升级脚本升级 nginx 把扩展编译进去;二是查看原本编译参数,加上 ngx_cache_purge 相关参数直接编译。

「Nginx 启用 FastCGI_Cache 静态化缓存加速 WordPress 网站博客:https://bdkp.net/19」

基于 OneinStack 升级脚本方法

下载、解压 ngx_cache_purge 安装包:

cd /root/oneinstack/src
wget --no-check-certificate -c -O ngx_cache_purge-2.3.tar.gz https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz
tar xzf ngx_cache_purge-2.3.tar.gz
cd /root/oneinstack

修改 OneinStack nginx 升级脚本:

nginx_modules_options 中增加扩展配置,在 oneinstack/include 目录,找到 upgrade_web.sh,将 ./configure ${nginx_configure_args} 修改为:

./configure ${nginx_configure_args} --add-module=../ngx_cache_purge-2.3

或者执行下面代码修改:

sed -i 's!{nginx_configure_args}!{nginx_configure_args} --add-module=../ngx_cache_purge-2.3!g' /root/oneinstack/include/upgrade_web.sh

建议开启 screen 进行编译,如:

screen -S ngx

执行脚本升级 Nginx:

/root/oneinstack/upgrade.sh

选择升级 nginx,输入需要升级的 nginx 版本号,静待升级完成,执行如下代码检查:

nginx -V 2>&1 | grep -o ngx_cache_purge

显示 ngx_cache_purge 表示已经安装成功。

直接加参数编译

cd /root/oneinstack/src
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
wget http://nginx.org/download/nginx-1.20.2.tar.gz
tar xzf ngx_cache_purge-2.3.tar.gz
tar xzf nginx-1.20.2.tar.gz
cd nginx-1.20.2
nginx -V #查看 nginx 编译参数,最后加上 --add-module=../ngx_cache_purge-2.3 参数
./configure --prefix=/usr/local/nginx --user=www --group=www \
--with-http_stub_status_module --with-http_v2_module --with-http_ssl_module \
--with-ipv6 --with-http_gzip_static_module --with-http_realip_module \
--with-http_flv_module --with-ld-opt=-ljemalloc \ # 蓝色部分为你网站当前编译参数,请根据实际修改
--add-module=../ngx_cache_purge-2.3
make  #编译
mv /usr/local/nginx/sbin/nginx{,_`date +%F`}  #备份nginx
cp objs/nginx /usr/local/nginx/sbin
nginx -V 2>&1 | grep -o ngx_cache_purge
# 显示 ngx_cache_purge 表示已经安装成功

配置 FastCGI_Cache 部分静态化 WordPress 加速

fastcgi_cache_path 放到 tmpfs 内存中,比放在硬盘上更快,内存小的话放硬盘也可以,毕竟现在很多 VPS 都是 SSD 硬盘,虽然速度肯定比不上内存,但是也不会太差。CentOS 内存目录在 /dev/shm,Ubuntu 和 Debian 在 /run/shm。使用 df -h /var/run 命令查看空间大小。

创建 FastCGI_Cache 缓存目录

比如,在 run/ 目录下创建 nginx-cache

mkdir -p  /var/run/nginx-cache

温馨提示:Debian 10 需要在 /etc/rc.local 或者 /usr/lib/tmpfiles.d/ 目录下新增 nginx-cache.conf 文件,内容为:

d /var/run/nginx-cache 0755 www www

否则 VPS 重启就没有 nginx-cache 这个文件夹了。

修改网站配置文件启用 FastCGI_Cache

下面为参考配置,蓝色字体部分为 FastCGI_Cache 相关配置,按需修改:

#如果缓存多站点则把下面四行放到 nginx.conf 中 
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:64m max_size=256m inactive=1d;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_cache_lock on;
fastcgi_cache_background_update on;


server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /usr/local/nginx/conf/ssl/example.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/example.com.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256';
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
ssl_stapling on;
ssl_stapling_verify on;
server_name example.com www.example.com;
##access_log /data/wwwlogs/example.com_nginx.log combined;
access_log /data/wwwlogs/example.com_nginx.log main;
index index.html index.htm index.php;
root /data/wwwroot/example.com;
if ($ssl_protocol = "") { return 301 https://$host$request_uri; }
if ($host != example.com) { return 301 $scheme://example.com$request_uri; }
include /usr/local/nginx/conf/rewrite/wordpress.conf;
#error_page 404 /404.html;
#error_page 502 /502.html;

###### fastcgi_cache ######
set $skip_cache 0;
set $skip_cache 0;

# POST 和带参数的请求不展示缓存
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# 指定页面不展示缓存
if ($request_uri ~* "clr=all|preview=true|/wp-admin/|/go/|/out/|/xmlrpc.php|wp-.*.php|/feed/|index.php|/comment-page-*|wp-sitemap*.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;
# }
# 登录用户不展示缓存
if ($http_cookie ~* "wordpress_logged_in") {
set $skip_cache 1;
}
# 缓存清理
location ~ /purge(/.*) {
allow 127.0.0.1; #也可以加上 VPS 公网 ip 地址
deny all;
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
}
###### fastcgi_cache end ######


include custom.conf;

location ~ [^/]\.php(/|$) {
#fastcgi_pass remote_php_ip:9000;
fastcgi_pass unix:/dev/shm/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-Cache "$upstream_cache_status From $host";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Cache-Control "max-age=0, public";
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 12h;
fastcgi_cache_valid 301 302 3d;
fastcgi_cache_valid 304 1d;

}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
#expires 30d;
#access_log off;
expires max;
}

location ~ .*\.(js|css)?$ {
expires 7d;
access_log off;
}
location ~ /\.ht {
deny all;
}
}

这里把「评论过的用户不展示缓存」部分注释掉了,除了登录用户外所有用户看到的都是缓存。另外,不需要缓存的重定向规则,需要放到「# 指定页面不展示缓存」之后,否则排除缓存规则无法生效。

比如,博主把 /go/ 外链跳转目录设置为不缓存,include custom.conf; 里面有跳转规则 rewrite ^/go/(.*)$ /ooxx/xxooxxoo.php?oox=$1 last;,那么 一定要把 include custom.conf; 放到「# 指定页面不展示缓存」之后,否则 /go/ 会被缓存。(亲测)

使 nginx 配置生效

nginx -t 先检查一下配置,确认无误,重启 nginx

service nginx reload

安装 Nginx Helper 插件

前面说过 FastCGI_Cache 不支持自动清除缓存,WordPress 可以安装 Nginx Helper 插件通过 nginx_cache_purge 接口实现自动清理缓存。

后台搜索 Nginx Helper 插件,安装,激活,Enable Purge,Caching Method 选 nginx Fastcgi cache (requires external settings for nginx),其余使用默认配置即可。

插件作者定义缓存路径是 /var/run/nginx-cache ,如果自定义缓存路径,会导致插件无法找到缓存文件删除!

解决办法是在 WordPress 根目录下 wp-config.php 文件中新增如下代码即可:

//根据实际情况定义缓存的存放路径
define( 'RT_WP_NGINX_HELPER_CACHE_PATH','/tmp/wpcache');

如果上述定义路径代码不生效,可以试试使用软连接:

ln -s /var/run/nginx-cache  /tmp/wpcache

检查 FastCGI_Cache 是否正常工作

打开网页,F12 打开开发者工具,查看 HTTP 的响应头部,可以看到 x-cache 状态。

HIT 代表命中缓存
MISS 代表没有找到缓存
BYPASS 代表跳过缓存
EXPIRED 代表缓存过期

还可以刷新站点,看缓存目录是否增大。

du -sh /var/run/nginx-cache

温馨提示:开启 FastCGI_Cache 需谨慎!!!上线前需先测试,修改主题解决以下两个问题:1.fastcgi_cache 可能会缓存评论者名称和邮箱信息;2. 如果在登陆状态回复评论,会缓存登陆界面。

详细方法参考后续资料:修改 WordPress 主题匹配 FastCGI_Cache 静态化缓存

参考资料

-- 完 --

退出移动版