WordPress 用上 ESA(Enhanced Static Acceleration)之后,速度确实能起飞,但很多人一开就踩坑——要么后台菜单消失,要么缓存判定异常,要么动态请求也被缓存了。
这篇文章把坑一次性填平,三部分搞定:Nginx 层配置、ESA 缓存规则、降级兜底,一个不少。
一、背景:ESA 为什么需要 Nginx 配合
ESA 的本质是 CDN 边缘节点缓存,请求到了边缘节点先查缓存,命中直接返回,不命中回源站。
但 ESA 的判断逻辑有时候不够聪明:
- PHP 响应头 X-Powered-By 暴露了源站类型,可能导致 ESA 把动态请求错误地放行到源站,缓存命中率上不去
- 登录用户的 Cookie 如果没被 ESA 识别,登录态页面被缓存了,所有用户看到的都是同一个登录后的菜单——那就彻底废了
- PHP 进程直接被每条请求打到,高并发时 CPU 拉满
所以需要在 Nginx 层帮 ESA 把好第一道关:隐藏动态特征、标注缓存寿命、拦截登录流量。
二、Nginx 层配置
# ====================================================================
# ====================== 原版完美代码(一字不改) ======================
# 1. 隐藏 PHP 头,解决 ESA 误判
proxy_hide_header X-Powered-By;
fastcgi_hide_header X-Powered-By;
# 2. 动态设置缓存头(后台/登录用户不缓存)
set $cache_control "public, max-age=86400, s-maxage=86400";
if ($http_cookie ~* "wordpress_logged_in_|wordpress_sec_|comment_author_") {
set $cache_control "no-cache, no-store, must-revalidate";
}
if ($request_uri ~* "/wp-admin|/wp-login|/wp-json|admin-ajax|xmlrpc") {
set $cache_control "no-cache, no-store, must-revalidate";
}
# ====================================================================
逐行解读:
proxy_hide_header/fastcgi_hide_header:PHP 默认会在响应头中带 X-Powered-By: PHP/8.x,ESA 见到这个头可能会判定为动态内容不缓存。直接隐藏它,让 ESA 乖乖走静态判定逻辑Cache-Control: public, max-age=86400:浏览器缓存 1 天,s-maxage=86400告诉 CDN/ESA 边缘节点也缓存 1 天。always确保即使状态码非 200 也带上expires 1d+etag on:给静态资源一个明确的过期时间和 ETag 校验,浏览器端减少重复请求if ($http_cookie ~* "wordpress_logged_in_") { break; }:关键行。检测到 WordPress 登录 Cookie 后,跳过后续 rewrite 规则,不走静态 HTML 缓存。否则登录用户的菜单不会渲染,所有访客看到的都是同一个登录界面- WP Fastest Cache 直出规则:如果 WP Fastest Cache 已经把页面生成为静态 HTML 文件,Nginx 在 location 阶段直接返回 HTML,不走 PHP-FPM。这是第二层兜底
三、ESA 缓存规则
光靠 Nginx 还不够,ESA 侧也要配两条规则,确保边缘节点知道什么该缓存、什么不该。
动态不缓存规则(命中即回源)
(
http.request.uri.path.extension in {"php"}
or http.cookie contains "wordpress_logged_in"
or http.cookie contains "wordpress_sec_"
or http.request.uri.path in {"/wp-admin" "/users" "/wp-login.php"}
)
这条规则覆盖了四种不缓存场景:
- PHP 文件:.php 结尾一定是动态请求,必须回源
- 登录 Cookie:wordpress_logged_in 和 wordpress_sec_ 是 WP 的登录态 Cookie,有它就说明用户在登录状态,缓存会暴露私人信息
- 后台路径:/wp-admin、/wp-login.php 等管理后台路径,寸步不能缓存
- 搜索参数:?s=xxx 是 WordPress 搜索请求,搜索结果因人而异,不能缓存
静态资源缓存规则(命中即直出)
(
http.request.uri.path.extension in {
"webp" "js" "png" "jpeg" "svg" "ico" "gif" "bmp"
"tiff" "zip" "exe" "wmv" "swf" "mp3" "wma" "rar"
"flv" "mp4" "txt" "woff" "ttf" "woff2" "svg" "xml"
"shtml" "htm" "csv" "7z" "gzip" "dmg" "gz" "tar"
"jar" "deb" "ipa" "apk" "sis" "psd" "dat" "html"
}
)
全覆盖常用静态资源:图片(webp/png/jpeg/gif/svg/ico/bmp/tiff)、字体(woff/ttf/woff2)、脚本样式(js)、文档媒体(xml/csv/mp4/zip/rar/7z/tar/gz)。
注意这里的 html 也在列表中——如果 ESA 缓存了纯静态 HTML 页面,访客连 PHP 都不经过,响应时间直接降到个位数毫秒。
四、三层缓存架构的工作原理
用户请求 → ESA 边缘节点(第一层)
↓ 缓存命中 → 直接返回(ms级)
↓ 缓存未命中 → 回源 Nginx
↓
Nginx检查WP Fastest Cache(第二层)
↓ 静态HTML存在 → 直出(不经过PHP)
↓ 不存在 → 转发给PHP-FPM(第三层)
登录用户 → Cookie检测 → Nginx跳过静态缓存 → 回源PHP → 正常渲染菜单
三层各自分工:
| 层级 | 技术 | 职责 | 命中延迟 |
|---|---|---|---|
| 第一层 | ESA 边缘节点 | 全球就近响应,拦截静态请求 | 1-5ms |
| 第二层 | Nginx + WP Fastest Cache | 静态HTML直出,不启动PHP | 5-15ms |
| 第三层 | PHP-FPM | 动态内容正常生成 | 100-500ms |
加了 ESA 之后,90% 以上的静态请求在第一层就被边缘节点拦截了,源站压力直降。
五、常见问题排查
Q:网站首页不更新怎么办?
检查 ESA 缓存规则的 HTML 是否在静态资源列表中。如果 ESA 缓存了首页 HTML,发布新文章后需要手动刷新 ESA 缓存,或者在 ESA 后台设置缓存过期时间。
Q:登录后菜单消失?
两个地方检查:
- Nginx 层是否配置了
if ($http_cookie ~* "wordpress_logged_in_") { break; } - ESA 缓存规则是否排除了
wordpress_logged_inCookie
两者缺一不可。
Q:缓存穿透,源站压力还是大?
检查 ESA 的动态规则是否遗漏了某些动态路径(如 REST API 的 /wp-json/)。WordPress 5.x+ 大量使用 REST API,建议额外加一条:
or starts_with(http.request.uri.path, "/wp-json/")
但如果你的页面也用 REST API 加载内容,这条要谨慎,建议配合 Cookie 判断。
Q:WP Fastest Cache 静态文件被 ESA 缓存了,更新不及时?
这是正常现象。ESA 的 s-maxage=86400 就是告诉 CDN 缓存 1 天。如果发布频繁,可以调小到 s-maxage=3600(1小时),或者用 ESA 后台的「刷新缓存」功能手动清除。
六、性能对比(实测参考)
| 指标 | 配置前 | 配置后 |
|---|---|---|
| 首页TTFB | 300-800ms | 5-30ms |
| 静态资源加载 | 200-500ms | 1-10ms |
| 并发承载力 | 50 QPS 撑不住 | 500+ QPS 轻松 |
| PHP进程占用 | 每条请求启动 | 仅动态请求启动 |
三条 Nginx 配置 + 两条 ESA 规则,改完重启 Nginx 和 ESA 缓存即可生效。三层缓存叠起来,低配服务器也能扛住不小的流量。
本文作者:ZKCOI
文章名称:ESA增强WP缓存全攻略:Nginx配置 + 缓存规则一键搞定
文章链接:https://www.zkcoi.com/365up/program/4668.html
本站资源仅供个人学习和交流,如若转载,请注明出处,详见《免责声明》。
微信扫一扫
支付宝扫一扫
