教程大全Nginx FastCGI,wordpress,WordPress优化

这两天一直在优化网站的速度,前面更换和删除了一些插件,并去掉了文章页底部的相关文章模块。现在页面动态加载速度基本在0.5秒左右。

为了进一步优化速度,决定抛弃WordPress插件式的缓存,选择不走 PHP 的 Nginx FastCGI 缓存。这样基本以静态方式访问可以大幅节省PHP运行占用的资源。遇到一些突发流量也能从容应对。

相关链接

Nginx Helper插件:https://cn.wordpress.org/plugins/nginx-helper/

插件可以在WP后台插件市场直接搜索“Nginx Helper”安装。

服务器环境

宝塔linux面板 7.7、Nginx 1.20.2、PHP 8.0、WordPress 6.9

其他环境的Nginx可能需要自己编译安装ngx_cache_purge模块。宝塔面板Nginx无需安装。

基本缓存原理

服务器Nginx通过ngx_cache_purge模块来生成页面缓存,存储到某个目录,有访客访问时直接将缓存文件返回给用户。

WordPress安装Nginx Helper插件,当文章更新时插件删除对应的缓存文件,或者是通过访问特定URL的方式告诉Nginx某个缓存已过期。

当页面尚未缓存时,访客访问该页面,Nginx会请求PHP把页面缓存下来。下次访客访问直接把缓存内容返回。不会运行PHP和读写数据库。

当存在页面缓存,如果页面更新,缓存已经过期时。访客访问该地址Nginx会通过PHP请求页面,返回给访客,并将页面缓存下来。

当存在页面缓存,缓存未过期时,访客访问页面Nginx会直接将缓存发送给用户。

如果需要清除全部缓存,可以直接将/wp-content/cache/fastcgi_cache缓存目录内的文件全部删除。

操作步骤

1.安装Nginx Helper插件

后台直接搜索安装,然后打开设置页面。按照下面的来设置。

上图中的缓存更新方式,如果你的缓存目录不在网站目录内,建议采用URL通知方式。否则可能遇到权限不足无法删除缓存的问题。

URL通知方式会产生额外的性能消耗。

博主是把缓存目录放到了/wp-content/cache/fastcgi_cache目录内,不存在权限问题。所以直接采用插件删除缓存文件的方式。

上图是缓存的清除规则,建议根据自己实际需求来选择。思考下发布或更新文章你要更新哪些页面缓存,发布评论时又要更新哪些页面缓存。

记得保存设置。

2.修改WordPress配置文件

网站根目录找到 wp-config.php 打开编辑

// 定义Nginx FastCGI存的自定义路径
define( 'RT_WP_NGINX_HELPER_CACHE_PATH', '/www/wwwroot/xxxxx/wp-content/cache/fastcgi_cache' );

在数据库配置下面加上这个配置,告诉WP我们的缓存文件位于哪里。

3..设置Nginx

因为本站是宝塔Linux面板环境,Nginx不需要再编译ngx_cache_purge模块,所以我们直接修改站点配置文件并重启Nginx就可以了。

如果是其他环境,请按照官方教程先编译ngx_cache_purge模块再设置站点配置文件。

在更改配置前,记得先复制保存一份原来的配置文件。用于配置错误时回滚初始配置。

打开站点设置,左侧找到配置文件。

FastCGI缓存设置

# FastCGI缓存设置
fastcgi_cache_path /www/wwwroot/xxxxxxx/wp-content/cache/fastcgi_cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m 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;

上面配置放到server配置前,可以直接放第一行。

/www/wwwroot/xxxxxxxx/wp-content/cache/fastcgi_cache是缓存文件的存放目录,我是直接放倒了站点目录内。

如果你放到服务器其他位置,请注意权限问题。宝塔面板用户文件夹权限设置为www用户组755权限。

如果权限搞不定,就将缓存清除方式改为URL通知。让Nginx去更新缓存。

如果你的服务器磁盘速度比较慢,内存又够用的话。你可以将一个文件夹挂载内存盘用来存储文件,读写速度会更快。但是服务器断电时缓存内容将会消失。

keys_zone=WORDPRESS:100m是缓存区域名WORDPRESS,100m是共享内存大小。1M大概是8千到1万缓存条数,100M大概能缓存80到100万,根据自己需求增减。

inactive=60m代表60分钟未被访问的缓存自动清理,可以将此值调大。比如设为3天/3d、7天/7d、30天/30d等。

max_size=1g代表缓存磁盘最大占用,根据自己需求设置。超过1G时nginx会自动清除老的缓存。

缓存规则

# 缓存跳过规则放在PHP配置前
set $skip_cache 0;
# POST请求和带参数的请求不缓存
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}

# 后台wp-admin、feed、sitemap不缓存
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.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;
}
# 结束

上面配置放在PHP配置前,宝塔面板的PHP配置是:

#PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-80.conf;
#PHP-INFO-END

PHP配置

因为宝塔面板默认PHP配置没有缓存设置,我们需要将原来的PHP配置改成新的。上面的宝塔默认PHP配置可以注释掉。

#PHP-INFO-START PHP引用配置,可以注释或修改
#include enable-php-80.conf;
#PHP-INFO-END

 # --- PHP-INFO-START 手动配置
location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi-80.sock;
fastcgi_index index.php;
include fastcgi.conf;
include pathinfo.conf;

# 缓存开启
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 301 302 7d;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

# 添加调试头在浏览器看缓存是hit还是miss
add_header X-FastCGI-Cache $upstream_cache_status;
}
#PHP-INFO-END

上面这一段替换掉原来的PHP配置。

禁止访问缓存目录

# 禁止访问Nginx缓存目录
location /wp-content/cache/fastcgi_cache {
deny all;
return 404;
}
# END

这一段可以放在宝塔默认禁止访问目录的下面。一键申请SSL的上面。

设置后完整的配置如下:

保存配置后记得重启Nginx。

# FastCGI缓存设置
fastcgi_cache_path /www/wwwroot/xxxxxxx/wp-content/cache/fastcgi_cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m 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;

server
{
listen 80;
listen 443 ssl http2;
server_name 你的域名;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/xxxxxxx;

# 开启 ETag
etag on;

#SSL-START SSL相关配置
#error_page 404/404.html;
ssl_certificate /www/server/panel/vhost/cert/xxxxxxx/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/xxxxxxx/privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
#SSL-END

#引用重定向规则
include /www/server/panel/vhost/nginx/redirect/xxxxxxx/*.conf;

#ERROR-PAGE-START
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END

# 缓存跳过规则放在PHP配置前
set $skip_cache 0;
# POST请求和带参数的请求不缓存
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}

# 后台wp-admin、feed、sitemap不缓存
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.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;
}
# 结束

#PHP-INFO-START PHP引用配置,可以注释或修改
#include enable-php-80.conf;
#PHP-INFO-END

# --- PHP-INFO-START 手动配置
location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi-80.sock;
fastcgi_index index.php;
include fastcgi.conf;
include pathinfo.conf;

# 缓存开启
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 301 302 7d;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

# 添加调试头在浏览器看缓存是hit还是miss
add_header X-FastCGI-Cache $upstream_cache_status;
}
#PHP-INFO-END

#REWRITE-START URL重写规则引用
include /www/server/panel/vhost/rewrite/xxxxxxx.conf;
#REWRITE-END

#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}

# 禁止访问Nginx缓存目录
location /wp-content/cache/fastcgi_cache {
deny all;
return 404;
}
# END

#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}

location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null; 
}
access_log /www/wwwlogs/xxxxxxx.log;
error_log /www/wwwlogs/xxxxxxx.error.log;
}

上面配置根据自己站点实际情况修改使用。保存配置后记得重启Nginx。

到这里我们设置就完成了,下面验证一下缓存吧。

测试缓存

如果你用的还有CDN,可能CDN会缓存我们添加的请求头,导致实际缓存页面后浏览器看到的请求头还是miss。这时我们查看CDN的请求头看下是否命中CDN就好。

或者暂时绕过CDN来查看请求头。

Ctrl+Shift+N开启浏览器隐私模式,并开启F12浏览器开发工具检查页面缓存。

上图可以看到我们缓存在Nginx和CDN上都是MISS未命中状态。

我们刷新几次网页。

刷新后可以看到我们CDN是缓存命中状态。

Nginx缓存提示未命中是因为CDN缓存了我们的请求头。下面我们绕过CDN看一下。

因为绕过了CDN,所以我们看不到CDN的请求头,能看到Nginx缓存是hit命中状态。

我们刷新下CDN缓存,重新通过CDN访问这个页面。

可以看到CDN和Nginx缓存都是命中状态了。

如果是登陆状态我们看到的请求头会是BYPASS,代表跳过缓存。