Varnish 缓存接入:WordPress 高流量站点的服务器加速方案

Varnish 缓存接入方案封面配图

当 WordPress 站点的日访问量从几千涨到十几万,很多站长会发现一个共同现象:服务器 CPU 并没有跑满,页面打开却越来越慢。问题的根源往往不在硬件性能,而在于每一次访问都触发完整的 PHP 解析和数据库查询。本文将讲解如何通过 Varnish 缓存(一种部署在 Web 服务器之前的内存缓存软件)帮助高流量 WordPress 站点显著降低响应时间,内容涵盖工作原理、接入步骤、配置要点与常见踩坑,读完即可在自己的服务器上落地实施。

Varnish 为什么能加速 WordPress

WordPress 的一个默认行为决定了它的性能上限:每个未缓存页面的请求,都要经过 Nginx/Apache 调用 PHP-FPM 执行几十条数据库查询,再渲染出完整 HTML。在峰值并发下,一个中型站点每秒几十个请求就会让数据库连接池吃紧。Varnish 的思路是把这份渲染结果直接存进内存:第一个访客触发完整渲染,之后所有访客在毫秒级拿到同一份 HTML 副本,后端完全不被打扰。

与插件类方案相比,它的差异体现在位置和效率上。缓存插件(如 W3 Total Cache)在 PHP 层工作,请求仍要进入 PHP 进程;Varnish 位于 Web 服务器之前,未命中缓存的匿名请求才会转发到后端。它的核心是 VCL(Varnish Configuration Language,专用配置语言)配置文件,通过一段规则代码声明”哪些请求查缓存、哪些直接放行”。通常只需要一台 4 核 8G 的 VPS(虚拟专用服务器) 承载 Varnish,就能扛住原本需要更高配置才能支撑的并发量。

Varnish 缓存与后端服务器关系图

在动手之前,先确认两个前提:域名解析与 SSL(安全传输协议)证书已就绪,且你有服务器 root 权限。如果是共享虚拟主机环境,无法安装系统级软件,这类加速需要改用缓存插件或升级到可自主管理的服务器方案。

接入前的架构规划

接入 Varnish 的本质是调整请求链路:访客先到 Varnish 监听的端口(默认 6081),未命中时再由 Varnish 转发给后端的 Nginx 或 Apache。规划时要处理的第一个问题是端口:常见做法是让 Varnish 监听 80/443 对外,Web 服务器退守到 8080 只接受 Varnish 的回源请求。如果服务器上还跑着其他站点或反向代理,需要先把端口分配画在纸上再动手,避免服务互抢端口。

第二个问题是 SSL 终止。Varnish 社区版原生不处理 HTTPS,主流做法有两种:其一,在 Varnish 前面再放一层 Nginx 或 CDN(内容分发网络)做 SSL 终止,再把解密后的流量交给 Varnish;其二,升级到支持原生 TLS 的 Varnish Plus 或使用 Hitch 这类专门的安全套接层代理。对多数站长,第一种方案更容易维护。

后端参数也需要按流量规模预设。以一台 8G 内存的服务器为例,建议给 Varnish 分配 2G 作为缓存空间(-s malloc,2G),其余留给 PHP-FPM 和数据库;缓存有效期(TTL)建议从 120 秒起步,观察命中率后再逐步拉长。更多服务器层面的资源规划思路,可以参考我们之前的服务器性能优化专题。

安装与基础配置

以 Ubuntu 22.04 为例,先完成软件安装与 Nginx 端口调整:

apt update && apt install varnish -y
# 将 Nginx 监听端口改为 8080(编辑 /etc/nginx/sites-available/wordpress)
systemctl restart nginx

接着修改 /etc/default/varnish(或 systemd 单元中的启动参数),把监听端口设为 80,并指定缓存空间大小:

DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,2G"

然后编辑 /etc/varnish/default.vcl,写入 WordPress 场景的基础规则:放行管理员与登录用户、剥离会话 Cookie、缓存其余 GET 请求。关键逻辑如下:

sub vcl_recv {
    # 管理后台与登录接口直接回源,不查缓存
    if (req.url ~ "^/wp-(admin|login)") { return (pass); }
    # 携带登录 Cookie 的请求回源,保证已登录用户看到实时内容
    if (req.http.Authorization || req.http.Cookie ~ "wordpress_logged_in") {
        return (pass);
    }
    # 匿名请求剥离跟踪类 Cookie 后查缓存
    unset req.http.Cookie;
    return (hash);
}

配置完成后重启服务并用 curl 验证响应头:curl -I https://example.com,看到 X-Varnish 和 X-Cache: HIT 字样即说明缓存层已生效。首次访问是 MISS 属正常现象,第二次请求就应命中。SSL 场景下这条链路通常配合 Nginx 的 443 终止,相关配置可参考这篇 WordPress 站点加速实践。

缓存失效与登录态处理

基础配置跑通后,真正的难点在于内容更新与缓存副本的一致性。假设你在后台刚发布了一篇文章,而首页的缓存副本还有两分钟才过期,读者看到的仍是旧列表。解决方式有两条路:缩短 TTL 让副本快速过期(简单但回源更频繁),或者配置清除策略,在发布动作发生时主动清掉对应缓存(精准但需要额外组件)。实践中常用的组合是插件 Purge 配合 VCL 监听 PURGE 请求,发布或更新文章时自动清除首页与该文章的缓存。

登录态是另一个必须提前设计的环节。上文 VCL 已把携带 wordpress_logged_in Cookie 的请求直接回源,这保证了编辑看到的后台和前台始终是实时的。相应地,WooCommerce 商城的购物车、结算页面也要加入放行名单,否则会出现”商品价格显示旧缓存”的售后问题。移动端与桌面端若使用不同主题,还需要在 hash 环节按 User-Agent 区分缓存副本。

观察命中率是调优的核心依据。执行 varnishstat 可以看到实时命中率、缓存空间占用和回源队列长度;健康的目标是缓存命中率超过 90%、后端请求下降一个数量级。如果命中率长期在 60% 以下,通常是 Cookie 剥离规则遗漏或 TTL 设置过短,值得优先排查。涉及跨多台服务器部署时,这类链路规划与独立服务器的资源调度还有不少可以展开的细节。

缓存命中率监控场景图

与 CDN 及缓存插件的取舍

不少站长会问:已经有 CDN 了,还需要 Varnish 吗?两者解决的是不同层面的问题。CDN 的边缘节点主要缓存静态资源(图片、CSS、JS),HTML 页面回源后仍要触发 PHP 渲染;Varnish 缓存的恰恰是这个动态渲染结果。两者叠加使用时,建议 CDN 回源指向 Varnish,形成”边缘缓存静态资源、源站内存缓存页面”的两层结构,这也是多数高流量 WordPress 站点的标准做法。如果预算或运维精力有限,先用缓存插件解决 80% 的问题,等流量增长到插件成为瓶颈时再上 Varnish,是更平缓的演进路径。

总结与行动建议

Varnish 接入的关键点可以归结为三步:先理清端口与 SSL 终止的链路,再写对 WordPress 场景的 VCL 规则(放行登录态、剥离 Cookie、缓存匿名 GET),最后围绕命中率和缓存失效持续调优。对日访问量十万级、服务器频繁过载的站点,这套方案的投入产出比相当可观;若你的站点仍在增长初期,也可以先从 Hostease 的WordPress 主机方案与缓存插件起步,把 Varnish 留到下一个流量台阶。如果你需要进一步评估自己站点的架构适配性,我们建议先用 varnishstat 在测试环境观察一周真实流量再做决定。

发表评论