核心是归一化语言标识:用map提取一级语言码(如zh、en),剔除accept-language权重与子标签,避免缓存分裂;再与设备、用户id等真实影响响应的维度组合成稳定key,如"$scheme://$host$uri|$device|$lang|$cookie_user_id"。

缓存键中纳入客户端语言环境,核心是提取稳定、可归一化的语言标识,而非直接拼接原始请求头。关键在于:只保留真正影响响应内容的语言维度,避免因 Accept-Language 头细节差异(如 zh-CN,zh;q=0.9,en;q=0.8)导致缓存分裂。
提取主语言码,忽略权重与冗余子标签
用 map 指令在 http 块中预处理 $http_accept_language,只取一级语言代码:
map $http_accept_language $lang { ~^zh.* "zh"; ~^en.* "en"; ~^ja.* "ja"; default "en"; }- 这样能把
zh-CN,zh;q=0.9和zh-TW都归为"zh",确保中文内容统一缓存 - 若业务需区分区域(如简体/繁体文案不同),再叠加
$geoip_country_code构成"zh-CN"或"zh-TW"
避免混入不相关变量,防止缓存失效
以下变量绝不能出现在 proxy_cache_key 中,否则每次请求语言标识看似相同,实际 key 却完全不同:
-
$request_time、$msec、$date_gmt等动态时间类变量 - 未清洗的完整
$http_accept_language—— 它可能含浏览器随机排序、权重、空格等不可控成分 - 无关 Cookie 或 Header,如
$cookie_sessionid(除非该 session 明确控制语言偏好)
结合登录态与设备类型,构建完整业务维度
语言只是其中一维,需与其他真实影响响应的变量组合使用:
- 已登录用户按
$cookie_user_id区分;未登录用户统一设为"guest" - 设备类型用预定义
$device(desktop/mobile/tablet),而非千变万化的$http_user_agent - 最终 key 示例:
proxy_cache_key "$scheme://$host$uri|$device|$lang|$cookie_user_id";
验证是否生效:看日志和响应头
配置后必须确认语言维度被正确识别并参与缓存判定:
- 添加日志格式:
log_format cache '$cache_key - $upstream_cache_status';,观察不同语言请求生成的 key 是否符合预期 - 用
curl -I请求带不同Accept-Language的 URL,检查X-Cache-Status是否从MIS变为HIT - 临时将 key 设为固定值(如
"test_lang_key"),确认多语言请求全部命中同一缓存,快速排除语法错误











