为了提升 WordPress 网站的加载速度,我在 CloudPanel 面板下启用了 Varnish 缓存,并结合 CLP Varnish Cache Plugin for WordPress 插件进行缓存管理。
虽然插件成功配置后返回了 x-cache-tags
等头信息,但我始终未能看到缓存是否真正“命中”的状态,如 X-Cache: HIT
,这使得调试缓存行为变得困难。
经过排查和实践,终于解决了这个问题。本文完整记录了整个分析和修复过程。
现象描述
初始配置完成后,我访问页面,响应头如下:
x-cache-tags: cafe,cafe-post-228,…
x-cache-age: 3200
cache-control: no-store, no-cache, must-revalidate, max-age=0
虽然 x-cache-tags
出现,说明 CLP 插件已生效,但却完全看不到 X-Cache
、X-Varnish
、Via
等关键字段,无从判断缓存是否命中。
排查步骤
1. 检查 Nginx 是否隐藏调试头
我的 CloudPanel 的 Nginx 配置中发现:
proxy_hide_header X-Varnish;
这会直接移除所有由 Varnish 添加的关键调试头。我尝试注释掉该行并重启 Nginx:
sudo systemctl reload nginx
但依然没有看到 X-Cache
等字段,说明还有其他地方在移除这些头。
2. 检查 default.vcl
中的 vcl_deliver
在 Varnish 的配置文件 /etc/varnish/default.vcl
中,发现如下配置:
unset resp.http.X-Varnish;
unset resp.http.Via;
这表示 Varnish 自身主动移除了这些响应头!
解决方案
✅ 修改 vcl_deliver
,添加命中调试头:
sub vcl_deliver {
set resp.http.X-Cache-Age = resp.http.Age;
unset resp.http.Age;
# 添加命中信息
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Varnish = req.xid;
set resp.http.Via = "1.1 varnish";
# 避免浏览器缓存
if (resp.http.Cache-Control !~ "private") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}
# 清理不必要头部(可保留)
unset resp.http.X-Powered-By;
unset resp.http.Server;
}
修改后重启 Varnish:
sudo systemctl restart varnish
测试结果
使用 curl -I https://www.example.com/
连续访问两次页面,结果如下
第一次访问:
x-cache: MISS
x-cache-age: 0
第二次访问:
x-cache: HIT
x-cache-age: 1
验证缓存已生效,并正确命中!
补充建议
- ✅ 使用
x-cache-tags
能配合 WordPress 内容更新实现精准清除缓存。 - ✅ 保留
X-Cache
头用于开发调试,生产环境可通过 IP 条件隐藏:
if (client.ip != "你的公网IP") {
unset resp.http.X-Cache;
unset resp.http.X-Varnish;
}
总结
在 CloudPanel 环境下使用 Varnish 缓存,如果需要调试是否缓存命中需要注意两点:
- Nginx 配置中不能隐藏调试头(proxy_hide_header)
- Varnish 的
vcl_deliver
中必须显式添加X-Cache
,X-Varnish
等头