Nginx fastcgi_cache 缓存加速 WordPress 站点
本教程介绍如何为 WordPress 站点配置 Nginx 的 fastcgi_cache 缓存,以加速 HTML 伪静态页面的访问。教程基于 LNMP 环境。
环境准备
本教程基于 LNMP 环境(例如军哥 LNMP 1.4 或更高版本)。请确保已安装以下或更高版本:
- MySQL 5.5.56
- PHP 5.5.38
- TCmalloc
安装 Nginx ngx_cache_purge 模块
首先,检查 ngx_cache_purge 模块是否已安装:
nginx -V 2>&1 | grep -o ngx_cache_purge
如果输出 ngx_cache_purge,则表示模块已安装。否则,请按以下步骤安装。
- 进入源码目录:
cd /usr/local/src - 下载 ngx_cache_purge 模块(请检查官网是否有更新版本):
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz - 解压:
tar zxvf ngx_cache_purge-2.3.tar.gz - 下载与当前环境匹配或更高版本的 Nginx 源码(例如 1.12.0):
wget http://nginx.org/download/nginx-1.12.0.tar.gz - 解压并进入目录:
tar zxvf nginx-1.12.0.tar.gz cd nginx-1.12.0 - 查看当前 Nginx 的编译参数:
nginx -V - 复制输出的编译参数,并添加
--add-module=../ngx_cache_purge-2.3。例如:./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-openssl=/root/lnmp1.4/src/openssl-1.0.2l --with-google_perftools_module --add-module=../ngx_cache_purge-2.3 - 编译(不要执行
make install):make - 备份原 Nginx 二进制文件并替换:
mv /usr/local/nginx/sbin/nginx{,_`date +%F`} cp objs/nginx /usr/local/nginx/sbin - 再次验证模块是否安装成功:
nginx -V 2>&1 | grep -o ngx_cache_purge
配置 fastcgi_cache
假设已通过 LNMP 创建了一个网站,域名为 www.example.com,配置文件为 /usr/local/nginx/conf/vhost/www.example.com.conf。
编辑该配置文件,在 server 块之前添加以下缓存路径和基本设置:
# 定义缓存存储路径和参数。请确保 /tmp/wpcache 目录存在,max_size 根据磁盘空间调整。
fastcgi_cache_path /tmp/wpcache levels=1:2 keys_zone=WORDPRESS:250m inactive=1d max_size=1G;
fastcgi_temp_path /tmp/wpcache/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;
然后,将 server 块内容替换或修改为以下配置(请根据实际情况修改域名、路径和 Sock 文件路径):
server {
listen 80;
server_name www.example.com;
index index.html index.htm index.php default.html default.htm default.php;
root /home/wwwroot/www.example.com;
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|purge=all") {
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;
}
location ~ [^/].php(/|$) {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock; # 请根据实际 PHP 版本确认 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";
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 301 302 1d;
}
location / {
try_files $uri $uri/ /index.php?$args;
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
}
# 缓存清理接口(可选,需配置允许的 IP)
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 你的服务器公网IP; # 请替换为实际 IP
deny all;
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
}
# 静态资源缓存
location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max;
}
location = /robots.txt { access_log off; log_not_found off; }
location ~ /. { deny all; access_log off; log_not_found off; }
access_log /home/wwwlogs/www.example.com.log;
}
# 可选的 www 重定向
server {
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
保存配置文件后,重启 LNMP 服务:
lnmp restart
WordPress 端配置
推荐安装 Nginx Helper 插件来管理缓存清理。在 WordPress 后台搜索并安装此插件。
在 wp-config.php 文件中添加以下定义,以指定缓存路径(需与 Nginx 配置一致):
// 定义 Nginx fastcgi_cache 缓存路径
define('RT_WP_NGINX_HELPER_CACHE_PATH', '/tmp/wpcache');
在 Nginx Helper 插件设置中,选择“Purge Method”为“Delete local server cache files”。
纯代码版缓存清理(可选)
如果不希望使用插件,可以将以下代码添加到主题的 functions.php 文件中,实现文章发布、评论更新时的自动缓存清理。
/**
* WordPress Nginx FastCGI 缓存清理代码 (Nginx-Helper 纯代码版)
*/
// 初始化配置
$logSwitch = 0; // 配置日志开关,1为开启,0为关闭
$logFile = '/tmp/purge.log'; // 配置日志路径
$cache_path = '/tmp/wpcache'; // 配置缓存路径,需与 Nginx 配置一致
// 清理所有缓存(仅管理员) 范例:http://www.domain.com/?purge=all
if (isset($_GET['purge']) && $_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.");
}
}
/**
* 删除目录及目录下所有文件或删除指定文件
* @param string $path 待删除目录路径
* @param bool $delDir 是否删除目录,true删除目录,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;
}
}
}
注意:管理员访问 http://你的域名/?purge=all 可以清理全部缓存。由于此 URL 本身也可能被缓存,建议在 Nginx 配置的跳过缓存规则中(如上文所示)添加 purge=all 排除。
其他性能优化建议(可选)
为了进一步提升 WordPress 性能,可以考虑以下组件:
- Memcached:用于数据库查询缓存,减轻数据库负载。可通过 LNMP 的
./addons.sh install memcached安装。注意 WordPress 通常使用php-memcache扩展。安装后,需将对应的object-cache.php文件放入网站的wp-content目录(非plugins目录)。 - OPcache:用于 PHP 脚本字节码缓存,加速 PHP 执行。LNMP 高版本 PHP 通常已内置,可通过
./addons.sh install opcache启用。注意 OPcache 与 eAccelerator 冲突。
配置完成后,访问网站并检查响应头中的 X-Cache 字段,显示 HIT 即表示缓存生效。