WordPress 缓存配置:插件选择、清除与缓存不生效
缓存插件装好、后台显示已启用,但页面源码里找不到缓存标记;或者文章改了三遍,前台还是昨天那版。这两类问题占我们接到的缓存工单的八成,原因基本不是插件坏了,而是把浏览器缓存、页面缓存、对象缓存当成了同一件事。
三种缓存各管一段,别混着谈
浏览器缓存靠响应头 Cache-Control 和 Expires,文件存在访客自己的电脑上,服务器端清不掉,只能靠改文件名或者加版本号参数让它失效。页面缓存把整页 HTML 存成静态文件,下次请求不经过 PHP 直接返回,Nginx 的 fastcgi_cache、LiteSpeed 的 LSCache、插件生成的 advanced-cache.php 都属于这一层。对象缓存把数据库查询结果放进内存,Redis 和 Memcached 是代表,它不减少 HTML 生成次数,只减少数据库查询次数。
三层解决的是不同瓶颈。数据库 CPU 打满,加页面缓存最有效;数据库查询多但 CPU 不满,加对象缓存更对症;首屏图片加载慢,两种缓存都不管用,那是 CDN 和图片压缩的事。
还有一层容易被忽略:缓存有效期。页面缓存 TTL 设成 24 小时,意味着发一篇新文章,没被主动清理的归档页最晚第二天才更新。企业站内容更新不频繁,TTL 可以给到 12 小时;新闻类站点给 10 到 30 分钟,靠主动清理兜底。TTL 不是越长越好,长 TTL 省的是服务器资源,付出的是内容新鲜度。
| 类型 | 存放位置 | 减少什么 | 典型实现 | 怎么清 |
|---|---|---|---|---|
| 浏览器缓存 | 访客本机 | 重复下载 CSS、JS、图片 | Cache-Control 响应头 | 改文件名或加版本号 |
| 页面缓存 | 服务器磁盘或共享内存 | PHP 执行与数据库查询 | LiteSpeed Cache、WP Rocket、fastcgi_cache | 后台「清除缓存」按钮 |
| 对象缓存 | Redis 或 Memcached | 数据库重复查询 | Redis Object Cache、W3 Total Cache | flushall 或插件按钮 |
| CDN 边缘缓存 | CDN 各地节点 | 回源流量与跨地域延迟 | 各 CDN 厂商的缓存规则 | 刷新 URL 或刷新目录 |
缓存插件怎么选:先看服务器,再看功能
服务器是 LiteSpeed 或 OpenLiteSpeed 的,直接用 LiteSpeed Cache,它在服务器层做缓存,不用每次请求都跑一遍 PHP,速度比纯插件方案快一个量级。宝塔面板里如果「软件商店 → 已安装」显示的是 nginx,那就走 Nginx 路线:预算够用 WP Rocket,配置项少、默认规则合理;预算为零用 WP Super Cache,简单但只有页面缓存;W3 Total Cache 功能最全也最容易配错,不建议新手直接上生产站。
判断缓存是不是真的生效,别信插件后台那个绿色对勾,看两个地方。一是页面源码末尾有没有类似 <!-- Cached by LiteSpeed Cache --> 的注释,二是响应头。
curl -sI https://example.com/ | grep -iE "cache|age|x-litespeed|cf-cache"
返回里出现 x-litespeed-cache: hit、x-cache: HIT 或者 age: 137,才算命中。age 为 0 或者没有这个头,说明请求每次都打到了源站。更细的插件选择可以看缓存插件那一篇的对比,这里只讲判断方法。
改了内容前台不变,按这个顺序清
清缓存的顺序错了会反复。正确顺序是从离用户最近的往最远的清,反过来做等于白做一次。
- 清插件页面缓存。后台顶部工具栏一般有 Clear Cache,或者「设置 → WP Rocket → 清除缓存」「LiteSpeed Cache → 工具栏 → 清空全部」。
- 清对象缓存。用 Redis 的命令行
redis-cli -a 密码 flushall,或者在插件里点 Flush Object Cache。这一步经常被漏掉,表现为「列表页更新了、详情页标题还是旧的」。 - 刷新 CDN。CDN 后台按 URL 刷新,批量改动就刷目录。有些 CDN 控制台刷新有延迟,别刷完立刻断言没生效。
- 绕开浏览器缓存看结果。
curl请求或者开无痕窗口,不要用普通窗口的 Ctrl+F5 判断服务器状态。 - 清 OPcache。改过 PHP 文件(比如 functions.php)却没反应,去宝塔的 PHP 设置里重载,或者
systemctl reload php-fpm。
登录用户看到缓存页的三个原因
现象很典型:管理员登录后台,前台右上角显示的是「登录」,点进文章页看到的是别人的用户名;或者会员中心显示未登录。原因无非三种。
- 页面缓存没排除登录 cookie。WordPress 登录后会写
wordpress_logged_in_xxx,缓存插件必须识别这个 cookie 并跳过缓存。LiteSpeed Cache 在「缓存 → 排除」里有对应选项,WP Rocket 默认会排除已登录用户,但有些主题用了自定义登录逻辑就不认了。 - CDN 缓存了带 Set-Cookie 的响应。源站返回了
Set-Cookie,CDN 仍然把这份 HTML 缓存下来发给所有人。要在 CDN 规则里设置「响应含 Set-Cookie 则不缓存」。 - 反代的缓存 key 只按 URL 算。多域名或者多语言站,缓存 key 里没带 Host 或语言 cookie,A 站的页面被发给 B 站访客,登录态也跟着串。
WooCommerce 和缓存的冲突
购物车的数据存在 cookie 和 session 里,页面缓存存的是某个时刻的 HTML 快照。两者一撞,就会出现「加了商品刷新后购物车空了」「A 用户看到 B 用户的购物车数量」这类事故。
处理办法是划出缓存禁区,而不是关掉缓存。把 /cart/、/checkout/、/my-account/、/wc-api/ 全部加进排除列表;缓存插件里打开「为登录用户单独缓存」的选项;wp-json/wc/store 这条 REST 路径要显式不缓存,否则购物车碎片(cart fragments)拿到的是旧数据。商品列表页和详情页可以正常缓存,它们是纯展示,没有用户态。
有一个反直觉的点:给登录用户单独缓存,等于给每个用户生成一份缓存,命中率几乎为零,还会把磁盘撑满。会员站更稳妥的做法是登录用户完全不走页面缓存,只保留对象缓存。这样前台是动态生成的,但数据库查询被 Redis 接住了,响应时间通常还能控制在 200 毫秒以内。
「启用了却不生效」的排查清单
如果按上面清完仍然没有缓存标记,顺着这五条往下查,基本能定位。
wp-config.php里define('WP_CACHE', true);没写或者写成了 false。插件启用时通常会自动加,但迁移或还原数据库后会丢。wp-content/advanced-cache.php不存在。这是插件写入的落盘文件,目录不可写时就写不进去,把 wp-content 权限改回 755、属主改成 www。- Nginx 没 include 缓存配置,或者
fastcgi_cache_path指定的目录属主不对,nginx 进程读不到缓存文件。 - 页面上有随机数、时间戳、CSRF token 之类每次不同的内容,缓存判断为不可缓存。
- 装了多个缓存插件,后装的把先装的
advanced-cache.php覆盖了,两个都在抢同一个钩子。这种冲突的表现是后台报错或者缓存时有时无,处理方式见插件冲突。
预防比排错省事。上线时把例外路径一次写全,改完主题模板固定清一次缓存,把 x-cache 响应头加进监控告警——命中率突然掉到 0,往往意味着缓存配置被覆盖了,而不是流量涨了。速度优化的整体顺序可以对照网站加速,缓存只是其中一层;如果站点面向全国或多地区用户,还要在缓存之上叠一层CDN 加速,否则缓存再好也解决不了物理距离带来的延迟。