站点在同一路径下按 Accept-Language 返回不同语言的内容,CDN 缓存键只用了 URL。第一个访客是中文,之后所有英文用户拿到的都是中文页。清一次缓存能管几分钟,随后又串回去。

排查方向其实有限,先把可能性排一排。缓存键没有包含 Accept-Language,不同语言的响应共用一份;回源响应里没有 Vary: Accept-Language,边缘无从区分;语言实际是靠 cookie 决定的,而缓存键同样忽略了 cookie;边缘节点数量多,逐个节点清理很难清干净。

带不同语言头请求同一地址,看返回内容是否相同

curl -s -H 'Accept-Language: en-US' https://www.example.com/ | grep -o '<html[^>]*>'

接着确认响应里有没有 Vary 头

curl -sI https://www.example.com/ | grep -i vary

然后把语言放进 URL 路径,缓存键天然分开

location /en/ { proxy_cache_key "$host$uri"; }

需要按头区分时补上 Vary 并清掉旧缓存

add_header Vary Accept-Language;

这台环境是别人交接的,不少默认值被动过,只能一项项核。

改完先别撤,确认这几项。英文请求拿到英文页,中文请求拿到中文页,缓存命中率仍在七成以上。

按 Accept-Language 分版本是共享缓存的天然敌人,能落到 URL 上就别靠请求头区分。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189