配置Nginx fastcgi_cache缓存为网站提速

最近一段时间我有空余时间便在折腾自己的WordPress,陆陆续续优化了页面显示和一些小的功能,偶然发现系统的Memcached并没有真正启用,且发现我单篇文章的数据库查询数都在100次左右,网站整体访问速度并不算快,于是着手对WordPress前后端进行性能优化,提高访问速度优化用户体验。此后我尝试了各种各样的方案,最后经我测试配置Nginx fastcgi_cache缓存可以达到立竿见影的效果,让访问速度从秒到了毫秒级,实现了真正的秒开!不知您给位有没有觉得我这里稍稍快了一些呢?

配置Nginx fastcgi_cache缓存为网站提速
让WordPress从秒级访问到毫秒级访问

1、WordPress性能优化一般有哪些

要优化自己的WordPress站点,首先要感知了解自己的网站访问效果到底如何。除了自身和访客的主观感知外,一般还可以用站长助手、Google PageSpeed Insights、Pingdom Website Speed Test等网站性能测试工具来细致地分析,后两个工具可以详细地分析我们站点访问的各项指标,有条件的同学可以以下。

这里我推荐在WordPressfooter.php中加一个小函数即echo get_num_queries()以了解咱们页面上每次的开销,同时打开Chrome无痕模式下的开发者模式(F12或CTRL+SHIFT+I),点到网络选卡,勾选停用缓存选项,然后刷新页面,这样可以准确的看到正常访问该页查询了多少次数据库、加载了多少资源、花费了多长时间等。


	</body>
<!--<?php echo get_num_queries().'次查询,耗时'.timer_stop(0).'秒。'; ?>-->
<!--将上一行目标代码作HTML注释并不影响其功能,实现前台页面隐藏-->
</html>

那么WordPress优化该从哪些方面入手呢?我认为至少有以下几个方面:1、服务器性能扩容,2、静态内容优化,3、使用CDN,4,网页延迟加载(lazyload),5、系统代码优化,6、使用缓存,7、服务器优化。目前看来我这里的静态内容亟待优化(单首页第一屏就会加载超过2.5MB的内容),没有使用缓存器和优化服务器。

本文主要讲述WordPress配置Nginx fastcgi_cache,是我个人的一次折腾记录(网上的教程很多,有些没说清楚(对于小白)),在此之前我还尝试了Memcached、Redis和各种WordPress缓存插件,为了节省篇幅,我给出的测试结果是:1、对象存储工具请无脑使用Memcached+batcache,小网站不要用Redis;2、WordPress缓存插件使用WP-Rocket或WP Super Cache即可,前者功能性能最佳,后者完全免费且持续更新。附赠Wp-rocket-v3.15.10 中文破解版免费下载(提取码:y4J9),本人亲测暂未发现错误和漏洞。

不过,目前上述两点我都没采用,一则是我安装Memcached失败了,第二则是发现装了这些WordPress缓存插件并没有给我的性能带来提高,有些甚至是副作用。倒是安装了正文即将介绍的Nginx fastcgi_cache,效果让人惊叹。Well, Let’s get started!


2、Nginx配置ngx_cache_purge模块

Nginx的Fastcgi cache是用来缓存用户请求,当用户下次再进行同样的访问的时候直接将缓存结果返回给用户,避免了Nginx再向上游请求结果的过程,使服务性能大幅度提升,如果服务是静态可缓存的话使用这个模块能够明显缩短用户请求时间同时节省服务器资源,大大提升服务的QPS。

个人一直用宝塔面板,这里也将以宝塔面板为例记录如何配置Nginx fastcgi_cache缓存为WordPress加速。宝塔在安装Nginx时就已经给编译了预装了ngx_cache_purge模块,在ssh命令行里输入nginx -V 2>&1 | grep -o ngx_cache_purge查看是否已正确编译该模块:

root@aliyun:~# nginx -V 2>&1 | grep -o ngx_cache_purge
ngx_cache_purge

如果一切正常,接下类开始配置服务器Nginx。在nginx管理-配置中的server前加入以下内容:

# nginx fastcgi cache 的 HTTP 配置START

#站点 1 缓存配置
fastcgi_cache_path /tmp/nginx-cache/shephe_com levels=1:2 keys_zone=SHEPHE.COM:100m inactive=1d max_size=5G;

#如果要开启更多站点缓存,参照第一行设置,注意每个站点的 缓存路径 和 keys_zone 要区分开

#站点 2 缓存配置
fastcgi_cache_path /tmp/nginx-cache/othersite_com levels=1:2 keys_zone=OTHERSITE.COM:100m inactive=1d max_size=5G;

#多站点时共用以下配置
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;

# nginx fastcgi cache END

Nginx fastcgi_cache缓存目录创建

对于如我这样的小白,需针对性解释下第一句配置:其中的/tmp/nginx-cache/shephe_com为站点1的缓存路径,在配置生效前,须先创建本目录并赋予其读写权限(0755或0777)。在宝塔面板中手动创建或命令行都行:

mkdir /tmp/nginx-cache/shephe_com
chmod 755 /tmp/nginx-cache/shephe_com

mkdir /tmp/nginx-cache/othersite_com
chmod 755 /tmp/nginx-cache/othersite_com

以上本例缓存设在了磁盘空间临时文件夹/tmp内,如果你的主机内存够,可以将缓存目录设在Linux虚拟的内存空间/dev/shm中,比如/dev/shm/nginx-cache/shephe_com/dev/shm这个目录是linux下一个利用内存虚拟出来的一个目录,这个目录中的文件都是保存在内存中,而不是磁盘上。其大小是非固定的,即不是预先分配好的内存来存储的,shm = shared memory。

Nginx fastcgi_cache关键配置基本解释

虽然配置中的注释已经很清晰了,但必须说明的是:如果你的主机上有多个站点,那么务必设置不同的缓存路径和keys_zone(缓存键),否则会出现缓存冲突,访问站点1会出现站点2的页面。后边跟的100m代表可以缓存键的最大内存,间接地定义了缓存的最大条数,该值不定义真正缓存文件空间大小;inactive定义了缓存有效期,默认为10m;max_size定义了缓存临时文件的最大空间,即本例/tmp/nginx-cache/temp文件夹最大空间,默认为无限大。

因此,如果您将采用内存空间作为Nginx fastcgi_cache缓存,必须要注意物理内存和max_size值大小的关系……如果本站要使用物理内存作为缓存空间的话,我可能会这样设置:fastcgi_cache_path /dev/shm/nginx-cache/shephe_com levels=1:2 keys_zone=SHEPHE.COM:32m inactive=60m max_size=128m。参考:Server FaultNginx ModuleLinode Akamai

本例Nginx完整配置备份(多站点)

如果您本台主机仅缓存单个站点,为了方便可以把上述Nginx配置写入网站配置文件中(置于最前),也是一种不错的选择。

user  www www;
worker_processes auto;
error_log  /www/wwwlogs/nginx_error.log  crit;
pid        /www/server/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;

stream {
    log_format tcp_format '$time_local|$remote_addr|$protocol|$status|$bytes_sent|$bytes_received|$session_time|$upstream_addr|$upstream_bytes_sent|$upstream_bytes_received|$upstream_connect_time';
  
    access_log /www/wwwlogs/tcp-access.log tcp_format;
    error_log /www/wwwlogs/tcp-error.log;
    include /www/server/panel/vhost/nginx/tcp/*.conf;
}

events
    {
        use epoll;
        worker_connections 51200;
        multi_accept on;
    }

http
    {
        include       mime.types;
		#include luawaf.conf;

log_format quic '$remote_addr|$remote_user|$time_local|$request|$status|$body_bytes_sent|$http_referer|$http_user_agent|$http3'; 
access_log /www/wwwlogs/quic_access.log quic;
		include proxy.conf;

        default_type  application/octet-stream;

        server_names_hash_bucket_size 512;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 50m;

        sendfile   on;
        tcp_nopush on;

        keepalive_timeout 60;

        tcp_nodelay on;

        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 64k;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_file_write_size 256k;
		fastcgi_intercept_errors on;

        gzip on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";

        limit_conn_zone $binary_remote_addr zone=perip:10m;
		limit_conn_zone $server_name zone=perserver:10m;

        server_tokens off;
        access_log off;


# nginx fastcgi cache 配置START
#站点 1 缓存配置
fastcgi_cache_path /tmp/nginx-cache/shephe_com levels=1:2 keys_zone=SHEPHE.COM:100m inactive=1d max_size=5G;

#如果要开启更多站点缓存,参照第一行设置,注意每个站点的 缓存路径 和 keys_zone 要区分开
#站点 2 缓存配置
fastcgi_cache_path /tmp/nginx-cache/othersite_com levels=1:2 keys_zone=OTHERSITE.COM:100m inactive=1d max_size=5G;

#多站点时共用以下配置
#fastcgi_temp_path /tmp/nginx-cache/temp;
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;
# nginx fastcgi cache END


server
    {
        listen 888;
        server_name phpmyadmin;
        index index.html index.htm index.php;
        root  /www/server/phpmyadmin;

        #error_page   404   /404.html;
        include enable-php.conf;

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

        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }

        location ~ /\.
        {
            deny all;
        }

        access_log  /www/wwwlogs/access.log;
    }
include /www/server/panel/vhost/nginx/*.conf;
}

3、网站配置ngx_cache_purge模块

上文Nginx完整配置的最后一句include**/*.conf,用于调用各个网站的配置文件,这是宝塔面板的一种高效管理手段。为了个性化配置,本例将Nginx ngx_cache_purge全局配置和站点* ngx_cache_purge配置分开,本站的配置如下,将这段配置插入在原配置文件#SSL-END之后。

#配置Nginx fastcgi_cache START
    set $skip_cache 0;
    #post 访问不缓存
    if ($request_method = POST) {
      set $skip_cache 1;
    }   
    #动态查询不缓存
    if ($query_string != "") {
      set $skip_cache 1;
    }   
    #后台等特定页面不缓存(其他需求请自行添加即可)
    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;
    }
    #此处查看网站配置上下文严格设置,如果你的网站使用PHP7.4,就写-74.sock
    location ~ [^/]\.php(/|$)
    {
        try_files $uri =404;
        fastcgi_pass unix:/tmp/php-cgi-82.sock;
        fastcgi_index index.php;
        include fastcgi.conf;  
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        #新增的缓存规则
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
        add_header X-Cache "$upstream_cache_status From $host";
        fastcgi_cache SHEPHE.COM;
        add_header Cache-Control  max-age=0;
        add_header Nginx-Cache "$upstream_cache_status";
        add_header Last-Modified $date_gmt;
        add_header X-Frame-Options SAMEORIGIN; # 只允许本站用 frame 来嵌套
        add_header X-Content-Type-Options nosniff; # 禁止嗅探文件类型
        add_header X-XSS-Protection "1; mode=block"; # XSS 保护
        etag  on;
        fastcgi_cache_valid 200 301 302 1d;
    }
    #缓存清理配置
    location ~ /purge(/.*) {
      allow 127.0.0.1;
      allow "112.124.26.230"; # 引号要保留
      deny all;
      fastcgi_cache_purge SHEPHE.COM "$scheme$request_method$host$1";
    }
    #配置Nginx fastcgi_cache EDN

WordPress配置Nginx fastcgi_cache注意事项

  1. add_header Cache-Control如果是动态内容要实时更新的话,可以设置为0,否则可以设置时间大一些,默认单位是秒;
  2. sock的路径一定要填对,否则会出现502错误;
  3. 代码里面的服务器公网IP换成你的服务器公网IP,须保留双引号;
  4. 可选缓存配置:某些主题如果移动端访问报错,可以设置不缓存移动端,参考写法:
    #不缓存移动端访问
    if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry|windowss(ce|phone))) {
            set $skip_cache 1;
    }
  1. 如果评论过的用户加载的是缓存,那应该是WordPress没有记住Cookie,尝试把以下代码加入到functions.php中:
//nginx-cache缓存配置代码
add_action('set_comment_cookies','coffin_set_cookies',10,3);
function coffin_set_cookies( $comment, $user, $cookies_consent){
   $cookies_consent = true;
   wp_set_comment_cookies($comment, $user, $cookies_consent);
}
  1. 启用fastcgi_cache缓存时,发现在Nginx配置文件中添加了Cache-Control信息,但是总是不生效。HTTP头部信息会总会包含以下信息:Cache-Control: no-store,no-cache,must-revalidate,post-check=0,pre-check=0 和 Pragma: no-cache,这时需要修改宝塔面板中php配置文件中的关键词session.cache_limiter,其默认值是 nocache ,将它设置为none即可。

本站完整配置文件备份

server
{
    listen 80;
	listen 443 ssl;
    http2 on;
    server_name shephe.com www.shephe.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/shephe.com;

    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #HTTP_TO_HTTPS_START
    if ($server_port !~ 443){
        rewrite ^(/.*)$  permanent;
    }
    #HTTP_TO_HTTPS_END
    ssl_certificate    /www/server/panel/vhost/cert/shephe.com/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/shephe.com/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  

    #SSL-END

    #配置Nginx fastcgi_cache START
    set $skip_cache 0;
    #post 访问不缓存
    if ($request_method = POST) {
      set $skip_cache 1;
    }   
    #动态查询不缓存
    if ($query_string != "") {
      set $skip_cache 1;
    }   
    #后台等特定页面不缓存(其他需求请自行添加即可)
    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;
    }
    #这里请参考你网站之前的配置,特别是sock的路径,弄错了就502了!如果你的网站使用PHP7.4,就写-74.sock
    location ~ [^/]\.php(/|$)
    {
        try_files $uri =404;
        fastcgi_pass unix:/tmp/php-cgi-82.sock;
        fastcgi_index index.php;
        include fastcgi.conf;  
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        #新增的缓存规则
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
        add_header X-Cache "$upstream_cache_status From $host";
        fastcgi_cache SHEPHE.COM;
        add_header Cache-Control  max-age=0;
        add_header Nginx-Cache "$upstream_cache_status";
        add_header Last-Modified $date_gmt;
        add_header X-Frame-Options SAMEORIGIN; # 只允许本站用 frame 来嵌套
        add_header X-Content-Type-Options nosniff; # 禁止嗅探文件类型
        add_header X-XSS-Protection "1; mode=block"; # XSS 保护
        etag  on;
        fastcgi_cache_valid 200 301 302 1d;
    }
    #缓存清理配置
    location ~ /purge(/.*) {
      allow 127.0.0.1;
      allow "112.124.26.230"; # 引号要保留
      deny all;
      fastcgi_cache_purge SHEPHE.COM "$scheme$request_method$host$1";
    }
    #配置Nginx fastcgi_cache EDN

    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    #error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END

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

    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/shephe.com.conf;
    #REWRITE-END

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

    #一键申请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/shephe.com.log;
    error_log  /www/wwwlogs/shephe.com.error.log;
}

最后测试配置文件(如果配置不对,宝塔面板一般会报错),再重启Nginx和PHP。不出意外的话现在缓存已经生效了。参考WordPress前端优化之Nginx fastcgi_cache缓存 – 老白博客

4、检查Nginx fastcgi_cache缓存状态

如果已经按照上述正确配置了Nginx并重启,那么fastcgi_cache缓存已经就已经生效了,为了避免浏览器缓存影响,CTRL+SHIFT+N打开Chrome无痕模式,然后按F12或CTRL+SHIFT+I打开开发者状态栏,定位到网络-文档,点击文档查看标头信息大致如下:

配置Nginx fastcgi_cache缓存为网站提速
检查Nginx fastcgi_cache缓存状态
配置Nginx fastcgi_cache缓存为网站提速
最后我把缓存放在内存空间里面去了,速度确实有略微提升,没开缓存时则接近甚至超过一秒

其中有Nginx-Cache这一状态便表示以上的工作做好了,这一状态一般有三个属性分别是MISS/BYPASS/HIT,代表:

  • MISS 表示未命中:即这个页面还没被缓存,新发布或刚被删除的页面,首次访问将出现这个状态
  • HIT 表示缓存命中:打开一个没被排除的页面,刷新两次一般就是这种状态
  • BYPASS 表不缓存:即页面路径在 Nginx 规则中被设置成不缓存(set $skip_cache 1;),比如 WP 后台和登录用户的

5、利用Nginx Helper清理fastcgi_cache缓存

Nginx Helper是为 WordPress fastcgi_cache缓存量身打造的一个插件,它轻量、无广告且完全免费,可以方便地在后台控制Nginx fastcgi_cache缓存的清理、控制和故障排查。在官方插件库里边搜索Nginx Helper安装并启用,进入后台设置后如下图所示:

配置Nginx fastcgi_cache缓存为网站提速
利用Nginx Helper清理fastcgi_cache缓存

Nginx Helper清理fastcgi_cache模式选择

①、purge 模式

这个模式需要保留上文 Nginx 配置中的 purge 清理路径,清理的时候会产生一个请求。

出于安全考虑,一般 purge 都不会完全开放!只有特定的 IP 可以访问,所以,如果用了 CDN 的朋友,再使用模式一,则需要在服务器上的 /etc/hosts 中将网站域名解析为服务器真实 IP,以便插件直接请求 purge 路径,而不用走 CDN 节点,避免请求被拒绝。还是没搞懂的话就放弃这个模式吧!

②、文件模式

模式二是直接清理对应的缓存文件,不需要请求 purge 这个清理路径,所以使用模式二,不需要配置上文 Nginx 的 purge 规则(我个人推荐使用这个模式)。

由于插件作者定义的缓存路径是 /var/run/nginx-cache,而我们可能会根据服务器实际情况来自定义缓存路径,这样一来,缓存路径的不同就会导致插件无法找到缓存文件并删除!解决办法是在插件中找到这一处路径,并替换成我们自己上边设置的路径 /tmp/nginx-cache/shephe_com。定义缓存路径的位置在/www/wwwroot/网站空间/wp-content/plugins/nginx-helper/includes/class-nginx-helper.php,约88行位置。

如果怕更新插件忘了改,那么最好是在 WordPress 根目录下的 wp-config.php 中新增如下代码即可(不知道添加到第几行的话,可以添加到 define('WPLANG', 'zh_CN'); 的后面。添加后建议重载一下PHP,确保变量生效(主要针对开启了 PHP 缓存的网站),参考Nginx开启fastcgi_cache缓存加速,支持html伪静态页面 – 张戈):

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

Nginx Helper开启Debug选项

一般没啥事儿的话不用Debug。第一个是日志选项,如果需要看日志还得在 wp-config.php 中增加 NGINX_HELPER_LOG开启日志并定义位置;第二个是在页面底部加上加载信息,和本文最开始的那个函数一样。

6、免插件清理fastcgi_cache(Nginx Helper纯代码版)

Nginx Helper这款插件主要用于Nginx fastcgi_cache 缓存或 Redis 缓存清理,用起来确实不错,但因为某些原因你实在不想用插件的话,也可以使用张戈大大的纯代码。

/**
* WordPress Nginx FastCGI 缓存清理代码(Nginx-Helper 纯代码版) By 张戈博客
* 文章地址:
* 转载请保留原文出处,谢谢合作!
*/
 
//初始化配置
$logSwitch  = 0;                  //配置日志开关,1 为开启,0 为关闭
$logFile="/tmp/purge.log";   //配置日志路径
$cache_path="/tmp/wpcache";     //配置缓存路径
 
//清理所有缓存(仅管理员) 范例:
if ($_GET['purge'] == 'all' && is_user_logged_in()) {
    if( current_user_can( 'manage_options' )) 
    {
        delDirAndFile($cache_path, 0);
    }
}
 
//缓存清理选项
add_action('publish_post', 'Clean_By_Publish', 99);                   //文章发布、更新清理缓存
add_action('comment_post', 'Clean_By_Comments',99);                   //评论提交清理缓存(不需要可注释)
add_action('comment_unapproved_to_approved', 'Clean_By_Approved',99); //评论审核清理缓存(不需要可注释)
 
//文章发布清理缓存函数
function Clean_By_Publish($post_ID){
    $url = get_permalink($post_ID);
 
    cleanFastCGIcache($url);        //清理当前文章缓存
    cleanFastCGIcache(home_url().'/');  //清理首页缓存(不需要可注释此行)
        
    //清理文章所在分类缓存(不需要可注释以下 5 行)
    if ( $categories = wp_get_post_categories( $post_ID ) ) {
        foreach ( $categories as $category_id ) {
            cleanFastCGIcache(get_category_link( $category_id ));
        }
    }
 
    //清理文章相关标签页面缓存(不需要可注释以下 5 行)
    if ( $tags = get_the_tags( $post_ID ) ) {
        foreach ( $tags as $tag ) {
	    cleanFastCGIcache( get_tag_link( $tag->term_id ));
        }
    }
}
 
// 评论发布清理文章缓存
function Clean_By_Comments($comment_id){
    $comment  = get_comment($comment_id);
    $url      = get_permalink($comment->comment_post_ID);
    cleanFastCGIcache($url);
}
 
// 评论审核通过清理文章缓存
function Clean_By_Approved($comment)
{
    $url      = get_permalink($comment->comment_post_ID); 
    cleanFastCGIcache($url);
}
 
//日志记录
function purgeLog($msg)
{
    global $logFile, $logSwitch;
    if ($logSwitch == 0 ) return;
    date_default_timezone_set('Asia/Shanghai');
    file_put_contents($logFile, date('[Y-m-d H:i:s]: ') . $msg . PHP_EOL, FILE_APPEND);
    return $msg;
}
 
// 缓存文件删除函数
function cleanFastCGIcache($url) {
    $url_data  = parse_url($url);
    global $cache_path;
    if(!$url_data) {
        return purgeLog($url.' is a bad url!' );
    }
 
    $hash        = md5($url_data['scheme'].'GET'.$url_data['host'].$url_data['path']);
    $cache_path  = (substr($cache_path, -1) == '/') ? $cache_path : $cache_path.'/';
    $cached_file = $cache_path . substr($hash, -1) . '/' . substr($hash,-3,2) . '/' . $hash;
    
    if (!file_exists($cached_file)) {
        return purgeLog($url . " is currently not cached (checked for file: $cached_file)" );
    } else if (unlink($cached_file)) {
        return purgeLog( $url." *** CLeanUP *** (cache file: $cached_file)");
    } else {
        return purgeLog("- - An error occurred deleting the cache file. Check the server logs for a PHP warning." );
    }
}
 
/**
 * 删除目录及目录下所有文件或删除指定文件
 * 代码出自 ThinkPHP:
 * @param str $path   待删除目录路径
 * @param int $delDir 是否删除目录,1 或 true 删除目录,0 或 false 则只删除文件保留目录(包含子目录)
 * @return bool 返回删除状态
 */
function delDirAndFile($path, $delDir = FALSE) {
    $handle = opendir($path);
    if ($handle) {
        while (false !== ( $item = readdir($handle) )) {
            if ($item != "." && $item != "..")
                is_dir("$path/$item") ? delDirAndFile("$path/$item", $delDir) : unlink("$path/$item");
        }
        closedir($handle);
        if ($delDir)
            return rmdir($path);
    }else {
        if (file_exists($path)) {
            return unlink($path);
        } else {
            return FALSE;
        }
    }
}

将这带代码引入进function.php,按注释改成自己配置的情况。现在发布/更新文章、评论提交/审核,就会自动删除当前文章缓存了,发布/更新文章还会清理首页、分类以及相关标签页缓存(不需要可根据代码中的注释进行屏蔽)。

另外,如果想清理全部缓存,可在管理员登陆状态下访问首页+?purge=all参数,比如:https://www.shephe.com//?purge=all,其他用户或访客访问这个地址则没有任何作用,如果还不放心也可以自行更改代码中的参数判断字符串。但需要注意的是这个URL本身也会被缓存,以至于只能清理一次缓存,后续刷新就没用了,所以需要在宝塔网站配置文件中去排除:

#后台等特定页面不缓存,请严格按照浏览器显示去添加,有无“/”是不同的页面
if ($request_uri ~* "purge=all|/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
     set $skip_cache 1;
}

最后,经过我几天的体验,发现至少有如下几个问题亟待解决,有无懂行的朋友?

  1. 清理缓存有时候会抽风,不稳定
  2. Nginx缓存导致WP-postviews工作异常(已解决)

本文收录于{牧羊人}

© 版权声明

相关文章

1 条评论

  • 龙笑天
    龙笑天 游客

    对NGINX不是很熟悉 不敢随便改动~

    中国广东广州市 联通
    回复