结论先说:如果同一份缓存内容在 Linux 源站与 Windows 构建机之间出现路径大小写不一致,最稳的统一映射不是逐条改缓存键,而是先确定一个规范形式(通常全小写),再让缓存键、源站文件系统、重定向规则三处都按同一规范生成和比对。这个结论只在“路径差异确实来自大小写,且不涉及内容本身不同”时成立;如果两台机器上真的存在两份内容不同的文件,仅统一大小写映射反而会把两份内容错误地合并成一份,问题会更隐蔽。
路径大小写差异最常见的表现是:请求 /Images/Logo.png 命中一份缓存,而请求 /images/logo.png 命中另一份或直接回源。要区分两种原因,可以做一个可重复的对照动作:
ETag 或 Last-Modified、以及响应体长度。ETag 或内容长度不同,说明源站上很可能存在两份内容,此时问题不是映射缺失,而是文件重复。这一步的结果直接决定下一步:前者要先清理重复文件,后者才适合统一映射。跳过这一步直接改缓存键,等于在没确认对象的情况下动手。
大小写映射不是单点配置,它需要在三个位置保持一致,否则改一处仍会被另一处覆盖:
/A/B 与 /a/b 命中同一份缓存,就要在键生成阶段把路径规范化为小写,而不是在命中失败后再补一条规则。一个假设例子:源站规范形式定为全小写,缓存键也按小写生成。请求 /Assets/App.js 时,先被 301 到 /assets/app.js,再由缓存按小写键查找。这样大小写不同的请求最终都收敛到同一份缓存对象。若只改了缓存键、没加重定向,源站仍可能因大小写收到 404,缓存里就会出现一份“命中但内容为空”的记录,反而更难排查。
最需要警惕的反例是:规范形式统一后,原本两个大小写不同、内容也不同的资源被合并。比如 /Config/Prod.json 与 /config/prod.json 分别存放生产与测试配置,内容不同。若只按小写统一映射,两者会命中同一份缓存,其中一个环境的配置会被错误覆盖。判断依据是:统一前后分别对比两个路径的响应体哈希,如果哈希不同却映射到了同一键,说明统一动作选错了对象,应改为保留区分或重命名文件,而不是继续合并。
另一个会让结论失效的条件是:路径差异其实来自 URL 编码或末尾斜杠,而不是字母大小写。这种情况下改大小写规则不会生效,需要先确认差异的真实来源。
确认属于大小写映射问题后,可以按以下顺序推进:先选定规范形式并写入构建或部署脚本,让落盘文件名与之一致;再调整缓存键生成规则,使其在比对前做同样的规范化;最后补一条从非规范形式到规范形式的 301,并观察一段时间内 404 与缓存未命中的变化。验收时不要只看“请求量下降”或“抓取量归零”就判定成功,这些现象也可能来自规则误伤或监控口径变化。更可靠的依据是:同一资源的两种大小写写法返回相同的 ETag,且源站日志中非规范路径的 404 数量下降。如果 404 没降反而升,说明重定向或落盘环节还有一处没对齐,应回到三个位置重新核对,而不是继续叠加缓存规则。