背景
上一篇文章中,我已经完成了 Polylang 英文站从:
https://www.shuijingwanwq.com/en/
迁移到:
https://en.shuijingwanwq.com/
并且确认了源站侧几个关键点:
Polylang 多域名模式正常
W3 Total Cache Page Cache 正常
W3 Total Cache Object Cache 正常
Redis 中旧的 Polylang option 已清理
en 与 www 的页面缓存目录已经分开
这一步完成后,英文子域名已经可以在源站正常访问。
但我的最终目标并不是只让 en.shuijingwanwq.com 能打开,而是希望形成更清晰的 CDN 结构:
www.shuijingwanwq.com → EdgeOne → 中文主站 + WordPress 后台
en.shuijingwanwq.com → Cloudflare → 英文前台
media.shuijingwanwq.com → Cloudflare → 上传媒体资源
也就是说,中文主站继续走 EdgeOne,英文前台单独交给 Cloudflare,媒体资源继续走 Cloudflare。
这样做的好处是:
英文站可以独立使用 Cloudflare 免费版缓存
中文主站继续保留 EdgeOne 的国内访问表现
媒体资源已经拆分,不会继续增加主站 CDN 流量压力
中英文前台缓存策略可以分开控制

一、先确认源站侧已经稳定
在切换 Cloudflare 橙云之前,必须先确认源站侧已经稳定。
因为如果源站侧 Polylang、W3TC、canonical、hreflang 还没有处理好,就直接启用 Cloudflare HTML 缓存,很容易把错误页面缓存下来。
前面我已经验证过:
https://www.shuijingwanwq.com/
→ lang = zh-CN
→ canonical = https://www.shuijingwanwq.com/
https://en.shuijingwanwq.com/
→ lang = en-US
→ canonical = https://en.shuijingwanwq.com/
https://en.shuijingwanwq.com/2026/07/05/18871/
→ lang = en-US
→ canonical = https://en.shuijingwanwq.com/2026/07/05/18871/
同时,W3TC 也已经为英文子域名单独生成页面缓存文件:
wp-content/cache/page_enhanced/en.shuijingwanwq.com/_index_slash_ssl.html
wp-content/cache/page_enhanced/en.shuijingwanwq.com/_index_slash_ssl.html_gzip
wp-content/cache/page_enhanced/en.shuijingwanwq.com/2026/07/05/18871/_index_slash_ssl.html
wp-content/cache/page_enhanced/en.shuijingwanwq.com/2026/07/05/18871/_index_slash_ssl.html_gzip
这说明源站侧的 WordPress、Polylang、W3TC 已经基本正常。

二、在 Cloudflare 中将 en 子域名从灰云切到橙云
接下来进入 Cloudflare:
DNS → en.shuijingwanwq.com
将这条 DNS 记录从灰云切换为橙云。
切换后,先不要急着启用 HTML 页面缓存规则。第一步只是确认 Cloudflare 代理是否真正接管了请求。
在服务器上执行:
getent ahosts en.shuijingwanwq.com | head
输出中可以看到 Cloudflare IP:
172.67.216.242 STREAM en.shuijingwanwq.com
172.67.216.242 DGRAM
172.67.216.242 RAW
104.21.78.52 STREAM
104.21.78.52 DGRAM
104.21.78.52 RAW
这说明 DNS 层面已经指向 Cloudflare。

然后继续通过 curl -v 确认连接到 Cloudflare IP:
curl -4 -v -o /tmp/en-cloudflare-test.html --max-time 20 "https://en.shuijingwanwq.com/?_cfcheck=$(date +%s)" 2>&1 | sed -n '1,80p'
关键输出:
Trying 172.67.216.242...
Connected to en.shuijingwanwq.com (172.67.216.242) port 443
再检查响应头:
curl -4 -sS -D - -o /dev/null --max-time 20 "https://en.shuijingwanwq.com/?_cfcheck=$(date +%s)" | grep -Ei "HTTP/|server:|cf-|cache|age|via|ray"
输出:
HTTP/2 200
server: cloudflare
cf-cache-status: DYNAMIC
cf-ray: a18ebf9e4cd9de50-AMS
这里的 cf-cache-status: DYNAMIC 是正常的,因为此时 Cloudflare 只是代理请求,还没有启用 HTML 页面缓存。

三、确认 Cloudflare 代理没有破坏 Polylang 输出
Cloudflare 接管后,还需要确认 Polylang 输出没有被破坏。
执行:
curl -4 -sS -D - -o /tmp/en-cloudflare-page.html --max-time 20 "https://en.shuijingwanwq.com/" | sed -n '1,30p'
grep -o '<html[^>]*>' /tmp/en-cloudflare-page.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-cloudflare-page.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]alternate["'\''"][^>]*hreflang=["'\''"][^>]*>' /tmp/en-cloudflare-page.html | head -n 10
输出:
HTTP/2 200
server: cloudflare
cf-cache-status: DYNAMIC
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
<link rel="alternate" href="https://www.shuijingwanwq.com/" hreflang="zh" />
<link rel="alternate" href="https://en.shuijingwanwq.com/" hreflang="en" />
这一步说明:
Cloudflare 橙云已经接管 en
Polylang 输出仍然是英文首页
canonical 正确
hreflang 正确
当前还没有启用 Cloudflare HTML 缓存

四、启用 Cloudflare HTML 页面缓存规则
确认代理没有问题后,再启用 Cloudflare 中提前配置好的 HTML 页面缓存规则。
我的规则设计大致是:
普通英文前台页面:允许 HTML 缓存
/wp-admin/:绕过缓存
/wp-login.php:绕过缓存
/wp-json/:绕过缓存
带 wordpress_logged_in Cookie:绕过缓存
在 Cloudflare Cache Rules 中,将之前已经配置但保持禁用的规则:
HTML 页面缓存(SEO安全)
切换为启用。
这里我没有修改规则表达式,也没有调整规则顺序。因为后台、登录页、REST API、登录用户绕过缓存的规则已经提前配置好。

启用后,先用带查询参数的 URL 测试规则是否匹配:
for i in 1 2 3
do
echo "================ request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-html-cache.html --max-time 20 \
"https://en.shuijingwanwq.com/?_cfhtmltest=$(date +%s)" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|vary|etag|last-modified|cf-ray"
grep -o '<html[^>]*>' /tmp/en-cf-html-cache.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-cf-html-cache.html | head -n 1
echo
sleep 2
done
输出中可以看到:
cache-control: max-age=14400
cf-cache-status: MISS
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
这里连续几次都是 MISS,原因是每次请求都带了不同的时间戳参数。
对 Cloudflare 来说:
/?_cfhtmltest=178367xxxx
每次都是不同 URL,所以每次都会生成新的缓存对象。
这个结果仍然有价值,因为它说明:
Cloudflare HTML 缓存规则已经匹配到了
页面仍然是 en-US
canonical 仍然指向 en
五、验证英文首页从 MISS 到 HIT
接下来测试不带查询参数的英文首页:
for i in 1 2 3
do
echo "================ request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-html-cache.html --max-time 20 \
"https://en.shuijingwanwq.com/" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|vary|etag|last-modified|cf-ray"
grep -o '<html[^>]*>' /tmp/en-cf-html-cache.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-cf-html-cache.html | head -n 1
echo
sleep 2
done
输出:
================ request 1 ================
HTTP/2 200
server: cloudflare
cache-control: max-age=14400
cf-cache-status: MISS
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
================ request 2 ================
HTTP/2 200
server: cloudflare
age: 4
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
================ request 3 ================
HTTP/2 200
server: cloudflare
age: 9
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
这一步说明英文首页已经进入 Cloudflare HTML 缓存。
而且命中缓存后,页面仍然是:
lang = en-US
canonical = https://en.shuijingwanwq.com/

六、验证英文文章页从 MISS 到 HIT
首页通过后,还需要验证英文文章页。
执行:
for i in 1 2 3
do
echo "================ request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-post-cache.html --max-time 20 \
"https://en.shuijingwanwq.com/2026/07/05/18871/" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|vary|etag|last-modified|cf-ray"
grep -o '<html[^>]*>' /tmp/en-cf-post-cache.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-cf-post-cache.html | head -n 1
echo
sleep 2
done
输出:
================ request 1 ================
HTTP/2 200
server: cloudflare
cache-control: max-age=14400
cf-cache-status: MISS
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/2026/07/05/18871/" />
================ request 2 ================
HTTP/2 200
server: cloudflare
age: 4
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/2026/07/05/18871/" />
================ request 3 ================
HTTP/2 200
server: cloudflare
age: 8
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/2026/07/05/18871/" />
这说明英文文章页也已经成功进入 Cloudflare HTML 缓存。

七、验证登录用户 Cookie 不会命中公开缓存
Cloudflare 缓存 HTML 页面时,最需要担心的不是能不能 HIT,而是登录用户会不会吃到公开缓存,或者公开用户会不会看到登录态页面。
因此必须验证带登录 Cookie 的请求不会 HIT。
执行:
for i in 1 2
do
echo "================ logged-in cookie request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-cookie-bypass.html --max-time 20 \
-H "Cookie: wordpress_logged_in_test=1" \
"https://en.shuijingwanwq.com/" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|vary|cf-ray"
grep -o '<html[^>]*>' /tmp/en-cf-cookie-bypass.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-cf-cookie-bypass.html | head -n 1
echo
sleep 2
done
输出:
HTTP/2 200
server: cloudflare
cf-cache-status: DYNAMIC
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
这里的关键是:
cf-cache-status: DYNAMIC
而不是:
cf-cache-status: HIT
这说明带 wordpress_logged_in 相关 Cookie 的请求不会命中 Cloudflare 公开 HTML 缓存。

八、验证 REST API 不会被缓存
WordPress REST API 也不能被 HTML 页面缓存。
执行:
for i in 1 2
do
echo "================ wp-json request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-rest-api.html --max-time 20 \
"https://en.shuijingwanwq.com/wp-json/" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|content-type|cf-ray"
head -c 120 /tmp/en-cf-rest-api.html
echo
echo
sleep 2
done
最终确认:
server: cloudflare
content-type: application/json; charset=UTF-8
cf-cache-status: DYNAMIC
只要 /wp-json/ 不是 HIT,就说明 REST API 没有被 Cloudflare HTML 缓存误缓存。

九、验证登录页与后台入口不会被缓存
继续验证登录页:
for i in 1 2
do
echo "================ wp-login request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-login.html --max-time 20 \
"https://en.shuijingwanwq.com/wp-login.php" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|content-type|set-cookie|cf-ray"
grep -o '<title[^>]*>.*</title>' /tmp/en-cf-login.html | head -n 1
echo
sleep 2
done
输出:
HTTP/2 200
content-type: text/html; charset=UTF-8
server: cloudflare
cache-control: no-cache, must-revalidate, max-age=0, no-store, private
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly
cf-cache-status: DYNAMIC
<title>Log In ‹ Yongye — WordPress</title>
再验证后台入口:
for i in 1 2
do
echo "================ wp-admin request $i ================"
curl -4 -sS -D - -o /tmp/en-cf-admin.html --max-time 20 \
"https://en.shuijingwanwq.com/wp-admin/" \
| grep -Ei "HTTP/|server:|location:|cf-cache-status|age:|cache-control|content-type|set-cookie|cf-ray"
echo
sleep 2
done
输出:
HTTP/2 302
location: https://en.shuijingwanwq.com/wp-login.php?redirect_to=https%3A%2F%2Fen.shuijingwanwq.com%2Fwp-admin%2F&reauth=1
server: cloudflare
cache-control: no-cache, must-revalidate, max-age=0, no-store, private
cf-cache-status: DYNAMIC
这说明:
/wp-login.php 不缓存
/wp-admin/ 不缓存
登录页会正常设置 wordpress_test_cookie
后台入口会正常跳转到登录页

十、进一步收敛:非 www 的后台入口统一跳转到 www
完成上面的验证后,我又想到一个问题:
虽然 en.shuijingwanwq.com/wp-admin/ 和 en.shuijingwanwq.com/wp-login.php 都不会被 Cloudflare 缓存,但从站点结构上看,英文子域名并不应该承担后台入口。
更合理的结构是:
英文前台:en.shuijingwanwq.com
WordPress 后台:www.shuijingwanwq.com
这样可以避免几个问题:
避免后台入口分散在多个 Host 上
避免登录 Cookie 在 en 与 www 之间混乱
避免后续安全规则、缓存规则越来越复杂
后台管理统一从 www 进入,更容易维护
所以我决定在 Nginx 层增加一段规则:
只要不是 www.shuijingwanwq.com
并且访问的是 /wp-admin/ 或 /wp-login.php
就统一 301 到 www.shuijingwanwq.com
注意,这里没有处理 /wp-json/。
因为前台页面、区块编辑器、REST API 输出仍可能使用对应语言域名下的 /wp-json/。目前让 /wp-json/ 保持 DYNAMIC 更稳,不需要强行跳转。
十一、添加 Nginx 后台入口跳转规则
先备份 Nginx vhost:
cp /usr/local/nginx/conf/vhost/www.shuijingwanwq.com.conf \
/usr/local/nginx/conf/vhost/www.shuijingwanwq.com.conf.bak.$(date +%Y%m%d%H%M%S)
然后在:
/usr/local/nginx/conf/vhost/www.shuijingwanwq.com.conf
中,放在:
include /usr/local/nginx/conf/rewrite/wordpress.conf;
之前,插入:
# Redirect non-www admin/login requests to the main www domain.
set $redirect_non_www_admin "";
if ($host != www.shuijingwanwq.com) {
set $redirect_non_www_admin "${redirect_non_www_admin}H";
}
if ($uri ~* "^/(wp-admin(?:/|$)|wp-login\.php$)") {
set $redirect_non_www_admin "${redirect_non_www_admin}U";
}
if ($redirect_non_www_admin = "HU") {
return 301 https://www.shuijingwanwq.com$request_uri;
}然后测试 Nginx 配置:
nginx -t
输出:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
最后重启 Nginx:
service nginx restart

十二、验证 en 后台入口会跳转到 www
添加规则后,先验证源站 Nginx 本身是否正确:
curl -k -sS -D - -o /dev/null --max-time 10 \
--resolve en.shuijingwanwq.com:443:127.0.0.1 \
"https://en.shuijingwanwq.com/wp-login.php" \
| grep -Ei "HTTP/|server:|location:|cache-control"
输出:
HTTP/2 301
server: nginx
location: https://www.shuijingwanwq.com/wp-login.php
说明源站规则正确。
然后通过公网和 Cloudflare 再验证:
for i in 1 2 3
do
echo "================ en wp-login public request $i ================"
curl -4 -sS -D - -o /dev/null \
--connect-timeout 10 --max-time 30 \
"https://en.shuijingwanwq.com/wp-login.php?_redirecttest=$(date +%s)" \
| grep -Ei "HTTP/|server:|location:|cf-cache-status|cache-control|cf-ray"
echo
sleep 2
done
输出:
HTTP/2 301
location: https://www.shuijingwanwq.com/wp-login.php?_redirecttest=1783679154
server: cloudflare
cf-cache-status: DYNAMIC
再验证后台入口:
https://en.shuijingwanwq.com/wp-admin/
→ 301
→ https://www.shuijingwanwq.com/wp-admin/
而 www 下的后台入口保持正常:
https://www.shuijingwanwq.com/wp-admin/
→ 302 到 www 的 wp-login.php
https://www.shuijingwanwq.com/wp-login.php
→ 200
这就完成了后台入口的收敛。

十三、最终回归验证:英文前台缓存没有受影响
最后还需要确认刚才的 Nginx 规则没有误伤英文前台。
执行:
for u in \
"https://en.shuijingwanwq.com/" \
"https://en.shuijingwanwq.com/2026/07/05/18871/"
do
echo "================ $u ================"
curl -4 -sS -D - -o /tmp/en-final-check.html --max-time 20 "$u" \
| grep -Ei "HTTP/|server:|cf-cache-status|age:|cache-control|location:|cf-ray"
grep -o '<html[^>]*>' /tmp/en-final-check.html | head -n 1
grep -o '<link[^>]*rel=["'\''"]canonical["'\''"][^>]*>' /tmp/en-final-check.html | head -n 1
echo
done
输出:
================ https://en.shuijingwanwq.com/ ================
HTTP/2 200
server: cloudflare
age: 28
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/" />
================ https://en.shuijingwanwq.com/2026/07/05/18871/ ================
HTTP/2 200
server: cloudflare
age: 28
cache-control: max-age=14400
cf-cache-status: HIT
<html lang="en-US">
<link rel="canonical" href="https://en.shuijingwanwq.com/2026/07/05/18871/" />
这说明:
英文首页仍然 HIT
英文文章页仍然 HIT
lang 仍然是 en-US
canonical 仍然指向 en
没有被后台跳转规则误伤

最终结构
到这里,英文子域名接入 Cloudflare 的配置已经完成。
最终结构是:
www.shuijingwanwq.com
→ EdgeOne
→ 中文前台 + WordPress 后台入口
en.shuijingwanwq.com
→ Cloudflare
→ 英文前台 + HTML 页面缓存
media.shuijingwanwq.com
→ Cloudflare
→ uploads 媒体资源
后台入口统一为:
https://www.shuijingwanwq.com/wp-admin/
https://www.shuijingwanwq.com/wp-login.php
非 www 域名下的后台入口统一跳转到 www:
https://en.shuijingwanwq.com/wp-admin/
→ https://www.shuijingwanwq.com/wp-admin/
https://en.shuijingwanwq.com/wp-login.php
→ https://www.shuijingwanwq.com/wp-login.php
Cloudflare 缓存验证结果:
普通 en 首页:
cf-cache-status: HIT
普通 en 英文文章页:
cf-cache-status: HIT
带 wordpress_logged_in Cookie:
cf-cache-status: DYNAMIC
/wp-json/:
cf-cache-status: DYNAMIC
/wp-login.php:
cf-cache-status: DYNAMIC
/wp-admin/:
cf-cache-status: DYNAMIC 或 301/302 跳转,不 HIT
这次配置的几个经验
这次配置让我更加确认一点:Cloudflare 缓存 WordPress HTML 页面时,不能只看是否出现 HIT。
真正要验证的是一整套链路:
DNS 是否已经切到 Cloudflare
响应头是否出现 server: cloudflare
HTML 页面是否从 MISS 到 HIT
html lang 是否正确
canonical 是否正确
hreflang 是否正确
登录 Cookie 是否绕过缓存
REST API 是否绕过缓存
登录页是否绕过缓存
后台入口是否绕过缓存
后台入口是否需要统一收敛到主域名
尤其是 Polylang 多域名模式下,如果只看到 cf-cache-status: HIT 就认为成功,其实是不够的。
还必须确认命中缓存后的页面仍然是:
<html lang="en-US">
canonical = https://en.shuijingwanwq.com/
否则就可能把错误语言、错误 canonical 或错误 Host 的 HTML 页面缓存到 Cloudflare。
这次最终采用的结构是:
中文主站继续走 EdgeOne
英文前台单独走 Cloudflare
媒体资源继续走 Cloudflare
后台入口统一回 www
对我当前的网站来说,这个结构比所有内容都放在一个 CDN 上更清晰,也更容易控制成本和缓存规则。
Linux 服务器运维、部署与线上故障排查
如果你的网站或后端服务部署在 Linux 服务器上,遇到访问异常、Nginx 配置问题、MySQL / Redis 异常、Docker 服务不可用、磁盘占满、CPU / 内存过高等问题,可以联系我做一次远程排查。
适合以下场景:
✅ 网站打不开或访问不稳定
✅ Nginx / PHP-FPM 配置异常
✅ MySQL / Redis 性能或连接问题
✅ Docker 服务部署与维护
✅ 服务器迁移与环境配置
✅ CPU / 内存 / 磁盘异常排查
服务内容:
✅ Linux 环境检查
✅ 网站部署与迁移
✅ Nginx / PHP-FPM / MySQL / Redis 排查
✅ Docker 配置与维护
✅ 服务器性能分析
✅ 长期远程运维支持
如需咨询,请联系我,并注明:Linux 运维咨询。
联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

发表回复