ARTICLE · 1000621
WordPress 缓存插件装了却没真正生效?实测让 Nginx 直接读取 Cache Enabler 静态缓存,绕过 PHP 和 MySQL
之前我一直认为:
WordPress 安装了 Cache Enabler,缓存文件正常生成,网站缓存就算完成了。
但这次真正排查以后发现,并不是这么回事。
Cache Enabler 成功生成缓存文件,不等于 Nginx 已经在使用这些缓存文件。
在很多 WordPress 网站上,实际访问链路依然是:
浏览器↓Nginx↓PHP↓WordPress↓MySQL↓生成 HTML
即使服务器目录里已经存在:
https-index.html.gz浏览器访问页面时,仍然可能重新启动 PHP、加载 WordPress、加载插件、查询数据库。
这次我分别在两种常用服务器环境下重新做了测试:
宝塔面板 + Nginx + WordPressLNMP + Nginx + WordPress
最终实现:
普通访客↓Nginx↓Cache Enabler 静态 HTML.gz↓直接返回浏览器
也就是说:
普通前台页面不再经过 PHP、WordPress 和 MySQL。
实际测试中,一个已经命中静态缓存的首页请求:
time_total: 0.026557大约 26ms。
当然,这个数字不能直接等同于浏览器完整打开网站的速度,因为页面还要加载图片、CSS、JS、字体等资源。
但从服务器处理 HTML 的角度来看:
Nginx 读取一个几十 KB 的静态 gzip 文件,和重新运行一遍 WordPress,完全不是一个级别的开销。
这篇文章把整个配置和排查过程完整整理下来。
一、Cache Enabler 到底缓存了什么?
Cache Enabler 是一个比较轻量的 WordPress 页面缓存插件。
它会把 WordPress 最终生成的 HTML 页面保存为静态文件。
例如首页可能生成:
wp-content/cache/cache-enabler/example.com/https-index.html.gz产品页面可能生成:
wp-content/cache/cache-enabler/example.com/product/example-product/https-index.html.gz如果启用了移动端缓存,还可能看到:
https-index-mobile.html.gz也就是说,第一次访问页面时:
Nginx↓PHP↓WordPress↓MySQL↓生成 HTML↓Cache Enabler 保存缓存
理论上,第二次访问就没有必要再运行 WordPress。
理想状态应该是:
Nginx↓https-index.html.gz↓浏览器
这才是我们真正想要的静态页面缓存。
二、缓存文件存在,并不代表缓存真的命中了
这是这次排查中最关键的一点。
我首先检查 Cache Enabler 的缓存目录。
宝塔环境通常可以执行:
find /www/wwwroot/example.com/wp-content/cache/cache-enabler \-type f | head -30
LNMP 一般是:
find /home/wwwroot/example.com/wp-content/cache/cache-enabler \-type f | head -30
如果看到:
https-index.html.gz说明:
Cache Enabler 插件本身已经正常工作。
例如:
/home/wwwroot/example.com/wp-content/cache/cache-enabler/example.com/https-index.html.gz产品页:
/home/wwwroot/example.com/wp-content/cache/cache-enabler/example.com/product/example-product/https-index.html.gz到这里,只能证明:
WordPress 成功生成了静态缓存。
但还不能证明:
Nginx 正在直接返回这些文件。
三、怎么判断请求到底有没有经过 PHP?
可以直接使用 curl。
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/
如果返回类似:
HTTP/2 200server: nginxcontent-type: text/html; charset=UTF-8x-powered-by: PHP/8.1link: ; rel=”https://api.w.org/”content-encoding: gzip
这里最值得注意的是:
x-powered-by: PHP/8.1以及 WordPress 返回的:
wp-json这说明:
当前请求仍然进入了 PHP 和 WordPress。
即使缓存目录里面已经存在 HTML 缓存,也没有真正实现 Nginx 直读缓存。
四、给 Nginx 增加一个 X-Cache 响应头
为了以后方便判断缓存状态,我直接在 Nginx 的静态缓存 location 中增加:
add_header X-Cache ”Cache-Enabler-HIT” always;这样以后只需要:
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/
看到:
x-cache: Cache-Enabler-HIT同时:
x-powered-by: PHP消失,就可以比较明确地判断:
Nginx 已经直接返回 Cache Enabler 的静态页面。
实际成功后的响应大概是:
HTTP/2 200server: nginxcontent-type: text/htmlcontent-length: 26393last-modified: Wed, 02 Sep 2026 05:19:13 GMTcontent-encoding: gzipvary: Accept-Encodingx-cache: Cache-Enabler-HITaccept-ranges: bytes
这里最关键的是:
x-cache: Cache-Enabler-HIT以及没有:
x-powered-by: PHP五、为什么之前 Nginx 可能一直命不中?
我之前排查过一个比较典型的问题。
很多网上的 Cache Enabler Nginx 配置会寻找:
index.html但我实际服务器生成的是:
https-index.html.gz甚至有些环境会生成:
https-index-webp.html.gz移动端则可能是:
https-index-mobile.html.gz如果你的 Nginx 写的是:
try_files /wp-content/cache/cache-enabler/${host}${uri}/index.html ...但实际文件是:
https-index.html.gz那么它永远不会命中。
所以我的原则是:
不要先复制网上的 Nginx 配置。
第一步先执行:
find /网站根目录/wp-content/cache/cache-enabler \-type f | head -30
看看你的 Cache Enabler 到底生成了什么文件。
再根据真实文件名写 Nginx。
六、最终实现的缓存逻辑
我的思路比较简单。
普通访客满足下面条件时尝试缓存:
GET / HEAD 请求没有 URL 参数没有登录 Cookie没有 WooCommerce Session不是后台不是 wp-json不是购物车不是 Checkout浏览器支持 gzip
然后:
请求↓判断能否缓存↓尝试读取 Cache Enabler 文件↓存在├─ 是 → Nginx 直接返回└─ 否 → WordPress
也就是两条线路。
第一条:
Cache HITNginx↓Cache Enabler↓HTML.gz↓Browser
第二条:
Cache MISSNginx↓PHP↓WordPress↓MySQL
七、为什么要绕过登录用户和 WooCommerce?
静态缓存最大的风险,不是“缓存没生效”。
而是:
缓存了本来不应该缓存的页面。
例如 WooCommerce。
如果用户 A 加了一件商品进入购物车:
woocommerce_items_in_cart如果这时候错误地把页面缓存成公共 HTML:
用户 B 可能看到用户 A 的购物车状态。
所以以下 Cookie 我会直接绕过缓存:
wordpress_logged_inwp-postpasscomment_author_woocommerce_items_in_cartwoocommerce_cart_hashwp_woocommerce_session_
下面这些页面也不进入公共静态缓存:
/wp-admin//wp-login.php/wp-json//xmlrpc.php/wp-cron.php/cart//checkout//my-account/
这一步非常重要。
八、带参数的 URL 我选择直接绕过
例如:
?s=sensor或者:
?wc-ajax=xxx以及:
?utm_source=google从极致性能角度来说,有一些参数其实可以忽略。
例如某些 UTM 参数理论上不会改变页面正文内容。
但我的服务器缓存策略比较保守:
有 query string↓直接进入 WordPress
也就是:
if ($query_string != ””) {return 419;}
这样虽然会牺牲少量缓存命中率,但稳定性更高。
对于企业站、SEO 内容站和产品展示站,我认为完全可以接受。
九、宝塔和 LNMP 的主要区别
两种环境的缓存逻辑其实完全一样。
主要区别是目录。
宝塔常见 WordPress 目录:
/www/wwwroot/example.comLNMP 常见:
/home/wwwroot/example.com宝塔的网站 Nginx 配置通常可以直接通过:
宝塔→ 网站→ 对应网站→ 设置→ 配置文件
修改。
LNMP 一般位于:
/usr/local/nginx/conf/vhost/比如:
/usr/local/nginx/conf/vhost/example.com.conf如果不知道哪个文件是真正生效的,可以:
grep -R -n ”server_name.*example.com” \/usr/local/nginx/conf/vhost /etc/nginx 2>/dev/null
可能会得到:
example.com.confexample.com.conf.bakexample.com.conf.bak-202608
真正需要修改的通常是:
example.com.conf不要改错备份文件。
十、配置完成后如何测试?
改完 Nginx 后第一件事永远不是 reload。
而是:
nginx -tLNMP 可以:
/usr/local/nginx/sbin/nginx -t必须看到:
syntax is oktest is successful
然后才:
/usr/local/nginx/sbin/nginx -s reload宝塔也可以直接通过面板重载 Nginx。
之后:
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/
成功后的核心标志:
x-cache: Cache-Enabler-HIT同时:
x-powered-by: PHP消失。
十一、实际速度测试
我测试使用:
curl -s \-o /dev/null \-w ”time_total: %{time_total}\n” \-H ”Accept-Encoding: gzip” \https://example.com/
返回:
time_total: 0.026557大约:
26ms这只是 HTML 主请求,不代表完整网页只需要 26ms。
但它能够说明一个问题:
服务器已经不再为每个普通访客重新运行 WordPress。
原来的流程:
PHP-FPM↓WordPress Core↓Theme↓Plugins↓MySQL↓HTML
现在变成:
Nginx↓几十 KB gzip 文件
对于内容型 WordPress 网站,这个优化的性价比非常高。
十二、什么网站特别适合这种方式?
我认为比较适合:
企业官网外贸 B2B 网站SEO 内容站产品展示网站Knowledge BaseBlog资讯网站
因为这类网站绝大部分访客只是:
进入页面↓阅读内容↓离开
没有登录状态,也没有复杂个性化数据。
对于这种请求,每次都重新运行 WordPress,其实没有必要。
十三、需要注意 CDN
如果前面还有 CDN,例如:
Cloudflare↓Nginx↓WordPress
这时候需要区分:
CDN HITNginx HITWordPress HIT
我现在增加:
X-Cache: Cache-Enabler-HIT主要用于确认:
源站 Nginx 是否直接读取了 Cache Enabler。
即使以后再叠加 CDN,也能比较方便地定位问题。
十四、完整配置一:宝塔 + WordPress + Cache Enabler
下面提供一套完整参考配置。
假设:
域名:example.comWordPress:/www/wwwroot/example.comCache Enabler:/www/wwwroot/example.com/wp-content/cache/cache-enabler/
使用之前,请根据自己的服务器调整:
域名网站目录SSL 证书PHP 版本
完整配置:
server{listen 80;listen [::]:80;server_name example.com www.example.com;root /www/wwwroot/example.com;location ^~ /.well-known/acme-challenge/{allow all;}location /{return 301 https://example.com$request_uri;}}server{listen 443 ssl http2;listen [::]:443 ssl http2;server_name example.com www.example.com;root /www/wwwroot/example.com;index index.php index.html index.htm;# ================================================================# SSL# ================================================================ssl_certificate/www/server/panel/vhost/cert/example.com/fullchain.pem;ssl_certificate_key/www/server/panel/vhost/cert/example.com/privkey.pem;ssl_protocols TLSv1.2 TLSv1.3;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;# ================================================================# 日志# ================================================================access_log /www/wwwlogs/example.com.log;error_log /www/wwwlogs/example.com.error.log;# ================================================================# Cache Enabler# ================================================================set $ce_device ””;# ------------------------------------------------# Mobile Cache# ------------------------------------------------if ($http_user_agent ~*”(Mobile|Android|Silk/|Kindle|BlackBerry|Opera Mini|Opera Mobi|iPhone|iPod)”){set $ce_device ”-mobile”;}# ------------------------------------------------# Cache Enabler 文件## 首页:## wp-content/cache/cache-enabler/# example.com/# https-index.html.gz## ------------------------------------------------set $ce_cache_file”/wp-content/cache/cache-enabler/${host}${uri}https-index${ce_device}.html.gz”;# ================================================================# wp-admin 自动补 /# ================================================================rewrite ^/wp-admin$ $scheme://$host$uri/ permanent;# ================================================================# WordPress 主入口# ================================================================location /{recursive_error_pages on;error_page 418 = @cache_enabler;error_page 419 = @wordpress;# 只处理 GET / HEADif ($request_method !~ ”^(GET|HEAD)$”){return 419;}# 浏览器必须支持 gzipif ($http_accept_encoding !~* ”gzip”){return 419;}# 带 URL 参数绕过缓存if ($query_string != ””){return 419;}# Authorization 绕过if ($http_authorization != ””){return 419;}# WordPress 登录状态if ($http_cookie ~*”(wordpress_logged_in|wp-postpass|comment_author)_”){return 419;}# WooCommerce Sessionif ($http_cookie ~*”(woocommerce_items_in_cart|woocommerce_cart_hash|wp_woocommerce_session_)”){return 419;}# WordPress 动态接口if ($uri ~*”^/(wp-admin|wp-login\.php|wp-json|xmlrpc\.php|wp-cron\.php|wp-comments-post\.php)”){return 419;}# WooCommerce 动态页面if ($uri ~*”^/(cart|checkout|my-account)(/|$)”){return 419;}# 普通访客尝试缓存return 418;}# ================================================================# Cache Enabler HIT# ================================================================location @cache_enabler{try_files $ce_cache_file @wordpress;gzip off;types { }default_type text/html;add_header Content-Encoding gzip always;add_header Vary ”Accept-Encoding” always;add_header X-Cache ”Cache-Enabler-HIT” always;}# ================================================================# Cache MISS → WordPress# ================================================================location @wordpress{try_files $uri $uri/ /index.php?$args;}# ================================================================# 禁止 uploads 执行 PHP# ================================================================location ~*^/wp-content/uploads/.*\.(php|php[0-9]+|phtml|phar)${deny all;}# ================================================================# PHP## 根据自己的宝塔 PHP 版本调整## ================================================================include enable-php-81.conf;# ================================================================# 图片# ================================================================location ~*\.(gif|jpg|jpeg|png|bmp|webp|avif|ico|svg)${expires 30d;access_log off;add_header Cache-Control ”public”;}# ================================================================# CSS / JS# ================================================================location ~* \.(css|js)${expires 12h;access_log off;add_header Cache-Control ”public”;}# ================================================================# 字体# ================================================================location ~*\.(woff|woff2|ttf|otf|eot)${expires 30d;access_log off;add_header Cache-Control ”public”;}# ================================================================# Let's Encrypt# ================================================================location ^~ /.well-known/acme-challenge/{allow all;}# ================================================================# 隐藏文件# ================================================================location ~ /\.{deny all;}}
宝塔环境需要特别注意:
如果原配置里存在:
include /www/server/panel/vhost/rewrite/example.com.conf;或者已经存在:
location /不要和上面的:
location /重复使用。
因为新的:
location @wordpress{try_files $uri $uri/ /index.php?$args;}
已经完成 WordPress Rewrite fallback。
十五、完整配置二:LNMP + WordPress + Cache Enabler
LNMP 常见:
网站目录:/home/wwwroot/example.comNginx 配置:/usr/local/nginx/conf/vhost/example.com.conf
完整配置如下:
server{listen 80;#listen [::]:80;server_name example.com;root /home/wwwroot/example.com;# ================================================================# 日志# ================================================================access_log /home/wwwlogs/example.com.access.log;error_log /home/wwwlogs/example.com.error.log warn;# ================================================================# Let's Encrypt# ================================================================location ~ /.well-known{allow all;}# ================================================================# 隐藏文件# ================================================================location ~ /\.{deny all;}# ================================================================# HTTP → HTTPS# ================================================================location /{return 301 https://$host$request_uri;}}server{listen 443 ssl http2;#listen [::]:443 ssl http2;server_name example.com;index index.html index.htm index.php default.html default.htm default.php;root /home/wwwroot/example.com;# ================================================================# 日志# ================================================================access_log /home/wwwlogs/example.com.access.log;error_log /home/wwwlogs/example.com.error.log warn;# ================================================================# SSL# ================================================================ssl_certificate/usr/local/nginx/conf/ssl/example.com/fullchain.cer;ssl_certificate_key/usr/local/nginx/conf/ssl/example.com/example.com.key;ssl_session_timeout 5m;ssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;ssl_ciphers”TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5”;ssl_session_cache builtin:1000 shared:SSL:10m;ssl_dhparam/usr/local/nginx/conf/ssl/dhparam.pem;# ================================================================# Cache Enabler# ================================================================set $ce_device ””;# ------------------------------------------------# Mobile Cache# ------------------------------------------------if ($http_user_agent ~*”(Mobile|Android|Silk/|Kindle|BlackBerry|Opera Mini|Opera Mobi|iPhone|iPod)”){set $ce_device ”-mobile”;}# ------------------------------------------------# Cache Enabler 文件# ------------------------------------------------set $ce_cache_file”/wp-content/cache/cache-enabler/${host}${uri}https-index${ce_device}.html.gz”;# ================================================================# wp-admin 自动补 /# ================================================================rewrite ^/wp-admin$ $scheme://$host$uri/ permanent;# ================================================================# WordPress 主入口# ================================================================location /{recursive_error_pages on;error_page 418 = @cache_enabler;error_page 419 = @wordpress;# GET / HEADif ($request_method !~ ”^(GET|HEAD)$”){return 419;}# gzipif ($http_accept_encoding !~* ”gzip”){return 419;}# URL 参数if ($query_string != ””){return 419;}# Authorizationif ($http_authorization != ””){return 419;}# WordPress 登录if ($http_cookie ~*”(wordpress_logged_in|wp-postpass|comment_author)_”){return 419;}# WooCommerce Sessionif ($http_cookie ~*”(woocommerce_items_in_cart|woocommerce_cart_hash|wp_woocommerce_session_)”){return 419;}# WordPress 动态路径if ($uri ~*”^/(wp-admin|wp-login\.php|wp-json|xmlrpc\.php|wp-cron\.php|wp-comments-post\.php)”){return 419;}# WooCommerce 动态页面if ($uri ~*”^/(cart|checkout|my-account)(/|$)”){return 419;}return 418;}# ================================================================# Cache Enabler HIT# ================================================================location @cache_enabler{try_files $ce_cache_file @wordpress;gzip off;types { }default_type text/html;add_header Content-Encoding gzip always;add_header Vary ”Accept-Encoding” always;add_header X-Cache ”Cache-Enabler-HIT” always;}# ================================================================# Cache MISS → WordPress# ================================================================location @wordpress{try_files $uri $uri/ /index.php?$args;}# ================================================================# 禁止 uploads PHP# ================================================================location ~*^/wp-content/uploads/.*\.(php|php[0-9]+|phtml|phar)${deny all;}# ================================================================# PHP# ================================================================include enable-php.conf;# ================================================================# 图片# ================================================================location ~*\.(gif|jpg|jpeg|png|bmp|swf|webp|avif|ico|svg)${expires 30d;access_log off;add_header Cache-Control ”public”;}# ================================================================# CSS / JS# ================================================================location ~* \.(js|css)${expires 12h;access_log off;add_header Cache-Control ”public”;}# ================================================================# 字体# ================================================================location ~*\.(woff|woff2|ttf|otf|eot)${expires 30d;access_log off;add_header Cache-Control ”public”;}# ================================================================# Let's Encrypt# ================================================================location ~ /.well-known{allow all;}# ================================================================# 隐藏文件# ================================================================location ~ /\.{deny all;}}
LNMP 如果原配置存在:
include rewrite/wordpress.conf;使用这套配置以后,需要删除或注释:
# include rewrite/wordpress.conf;否则可能和新的 WordPress fallback 重复。
十六、修改之前一定备份
例如:
cp example.com.conf \example.com.conf.bak-cache
宝塔也建议先复制原配置。
然后:
nginx -t或:
/usr/local/nginx/sbin/nginx -t测试通过以后再 reload。
千万不要:
修改配置↓直接重启
如果 Nginx 配置写错,线上网站可能直接打不开。
十七、最终验证方法
第一步:
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/
期待:
x-cache: Cache-Enabler-HIT第二步:
检查:
x-powered-by: PHP是否消失。
第三步:
测试一个明确已经存在缓存的内页:
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/product/example-product/
同样应该:
x-cache: Cache-Enabler-HIT第四步:
测试一个不存在的页面:
curl -I \-H ”Accept-Encoding: gzip” \https://example.com/cache-test-not-exist/
应该正常进入 WordPress,然后返回:
404而不是把错误页面当缓存返回。
十八、写在最后
这次重新折腾 WordPress 缓存之后,我最大的一个认识就是:
缓存插件“工作正常”和服务器“真正使用缓存”,完全是两个概念。
很多时候我们看到:
Cache Enabled看到:
wp-content/cache/里面已经有很多文件,就认为优化完成了。
其实请求可能还是:
Nginx↓PHP↓WordPress↓MySQL
而我现在更愿意直接确认:
X-Cache: Cache-Enabler-HIT然后看:
x-powered-by: PHP是否消失。
只有这样,我才认为:
服务器真正绕过了 WordPress 动态执行。
对于内容型 WordPress 网站,我现在比较喜欢这样的结构:
CDN↓Nginx↓静态 HTML
只有真正需要动态内容的时候:
Nginx↓PHP↓WordPress↓MySQL
这种思路并不复杂,但实际效果非常直接。
最后还是那句话:
服务器优化第一原则不是追求极限速度,而是保证稳定。
所以任何线上环境修改之前:
先确认缓存文件↓先备份↓修改配置↓nginx -t↓确认成功↓reload↓curl 验证
一步都不要省。
当你真正看到:
x-cache: Cache-Enabler-HIT并且:
x-powered-by: PHP消失的时候,才说明这次 WordPress 静态缓存优化真正完成了。