配置 Nginx FastCGI 缓存:全面提升网站加载速度

配置 Nginx FastCGI 缓存:全面提升网站加载速度

文章目录
文章目录
  1. 1. WordPress 性能优化一般有哪些
  2. 2. Nginx 配置 ngx_cache_purge 模块
  3. 3. 网站配置 ngx_cache_purge 模块
  4. 4. 检查 Nginx fastcgi_cache 缓存状态
  5. 5. 利用 Nginx Helper 清理 fastcgi_cache 缓存
  6. 6. 免插件清理 fastcgi_cache(Nginx Helper 纯代码版)

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

让 WordPress 从秒级访问到毫秒级访问

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

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

这里我推荐在主题 footer.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、服务器优化。目前看来 Kevin's Space 这里的静态内容亟待优化,因为它单首页第一屏就会加载超过 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

2.1 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。

2.2 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

2.3 本例 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

3.1 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 即可。

3.2 本站完整配置文件备份

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 ^(/.*)$ https://$host$1 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  https://$host$request_uri;

    #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;),比如用户登录时。

5. 利用 Nginx Helper 清理 fastcgi_cache 缓存

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

利用Nginx Helper清理fastcgi_cache缓存
利用 Nginx Helper 清理 fastcgi_cache 缓存

5.1 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');

5.2 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 张戈博客
* 文章地址:https://zhang.ge/5112.html
* 转载请保留原文出处,谢谢合作!
*/
 
//初始化配置
$logSwitch  = 0;                  //配置日志开关,1 为开启,0 为关闭
$logFile    = '/tmp/purge.log';   //配置日志路径
$cache_path = '/tmp/wpcache';     //配置缓存路径
 
//清理所有缓存(仅管理员) 范例:http://www.domain.com/?purge=all
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:http://www.thinkphp.cn/code/1470.html
 * @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 工作异常(已解决)
1920 1280 Kevin's
「配置 Nginx FastCGI 缓存:全面提升网站加载速度」有 28 条评论
  • […] Nginx fastcgi_cache 和 Memcached 内存缓存来提速 […]

  • […] 等等还没完,哪有这么顺利的事情呐…我本人在配置 Nginx fastcgi_cache 缓存为网站提速就提过,我本是要先安装 Memcached 对数据进行缓存,然后再安装 fastcgi 让它两相互配合使用,不幸当时安装 Memcached 失败了。那会儿我拿着那段报错提示搜刮了中文、英文、日文甚至俄文的相关资料,均没有获得正确的解决方案,错误提示如下: […]

  • 织梦岁月
    04/09/2024 at 21:27 回复

    大佬啊,我的博客总觉得慢,那个评论特别特别慢,也不知道怎么解决,以后多来你这里学习。。

    • 的头像
      Kevin
      04/10/2024 at 12:04 回复

      评论特别慢考虑函数优化(这个非科班出身不用想了),或者提高服务器性能,再或者搞对象缓存

    • Pipu
      04/14/2024 at 11:30 回复

      去 Wp 后台,设置,讨论。
      把有人发表评论时和有评论等待审核时前面的打勾去掉。立竿见影。

      • 的头像
        Kevin
        04/14/2024 at 11:59 回复

        好办法!

  • 陶小桃Blog
    04/09/2024 at 14:48 回复

    你的网站速度还是蛮不错的啊

    • 的头像
      Kevin
      04/10/2024 at 12:05 回复

      这几天瞎搞似乎又变卡了不少哎

  • 二猫
    04/06/2024 at 21:42 回复

    速度太快了,大受震撼😘

  • 老麦
    04/05/2024 at 15:46 回复

    有一说一,你的Wordpress站点优化得真好,都说Wordpress慢,我一直认为,只要优化好,速度还是很快的。

    • 的头像
      Kevin
      04/06/2024 at 00:48 回复

      你那个明显更快,而且用的香港服务器~
      我最近也是瞎折腾,搞了这一阵就是明年的事儿了~~一般至少一年才折腾一回

  • wu先生
    04/04/2024 at 18:56 回复

    技术文,不日月觉历。

  • dujun
    04/03/2024 at 20:19 回复

    访问很快

  • 1900
    04/02/2024 at 22:44 回复

    WordPress折腾的东西是挺多的,以前玩的时候也成天研究这些。
    (另外我你博客里会偶发性的出现碰到带滚动条的pre标签时会出现无法向下滚动的情况,鼠标手动拖动滚动条后又会恢复正常)

    • 的头像
      Kevin
      04/07/2024 at 17:12 回复

      内嵌滚动内容不都是这样么?

  • TeacherDu
    04/02/2024 at 18:40 回复

    好详细啊,这个实用~

    • 的头像
      Kevin
      04/07/2024 at 17:11 回复

      不算教程,专门写的记录贴,就怕哪天自己又需要用了,记不住。。

  • w4j1e
    04/02/2024 at 15:16 回复

    访问确实很快,文章一点就开。
    动态网站程序使用 CDN 带来的提升可能相较于静态网站比较有限吧。

    • 的头像
      Kevin
      04/07/2024 at 17:10 回复

      跟存储服务器很有关系吧,我想如果我的服务器是2m带宽的话,不上CDN恐怕狠恼火

  • hary
    04/02/2024 at 14:08 回复

    佬,你站点好快啊,下面图文的博客也很快,都是秒开的,优化的好啊

    • 的头像
      Kevin
      04/07/2024 at 17:03 回复

      瞎折腾,最近这段时间折腾完毕就会回归博客(个人站)的本质了

  • obaby
    04/02/2024 at 09:44 回复

    好绿

  • 灰常记忆
    04/02/2024 at 00:26 回复

    速度很快 我现在求稳

    • 的头像
      Kevin
      04/07/2024 at 16:54 回复

      稳稳当当

  • Jeffer.Z
    04/01/2024 at 22:45 回复

    你别说啊,速度确实快了好多啊。

  • Jeffer.Z
    04/01/2024 at 22:44 回复

    Memcached+batcache和supercache有没有冲突啊。我之前用redis结果被攻击打的报错就不敢用了。

    • 的头像
      Kevin
      04/07/2024 at 16:54 回复

      应该是没有,一个是数据对象存储,一个是直接缓存HTML页面,我试用了下来发现效果一般就停掉了,你描述的这几个东西我认为都可以停掉,用本文中哪个 WP rocket 插件就可以了

  • S
    04/01/2024 at 21:31 回复

    马克。

发表评论

请输入关键词…