网站缓存:文件路径大小写差异引发问题时怎样统一映射

📍 WDQWDWQD987AAAAA:142.132.135.121
📱 Mozilla/5.0 (compatible; QlyzeBot/1.0; +https://app.qlyze.io/bot)
🔗 /e6211364d88c.html
📄

网站缓存:文件路径大小写差异引发问题时怎样统一映射

结论先说:如果同一份缓存内容在 Linux 源站与 Windows 构建机之间出现路径大小写不一致,最稳的统一映射不是逐条改缓存键,而是先确定一个规范形式(通常全小写),再让缓存键、源站文件系统、重定向规则三处都按同一规范生成和比对。这个结论只在“路径差异确实来自大小写,且不涉及内容本身不同”时成立;如果两台机器上真的存在两份内容不同的文件,仅统一大小写映射反而会把两份内容错误地合并成一份,问题会更隐蔽。

先判断差异是大小写还是内容本身

路径大小写差异最常见的表现是:请求 /Images/Logo.png 命中一份缓存,而请求 /images/logo.png 命中另一份或直接回源。要区分两种原因,可以做一个可重复的对照动作:

这一步的结果直接决定下一步:前者要先清理重复文件,后者才适合统一映射。跳过这一步直接改缓存键,等于在没确认对象的情况下动手。

统一映射要同时约束三个位置

大小写映射不是单点配置,它需要在三个位置保持一致,否则改一处仍会被另一处覆盖:

  1. 缓存键的生成规则。多数缓存系统默认把完整 URL 当作键,路径部分大小写敏感。如果希望 /A/B 与 /a/b 命中同一份缓存,就要在键生成阶段把路径规范化为小写,而不是在命中失败后再补一条规则。
  2. 源站文件系统。Linux 文件系统区分大小写,Windows 不区分。如果构建产物在 Windows 上生成、部署到 Linux,原本“能访问”的路径可能在 Linux 上变成 404。这种情况下,映射统一必须落在部署环节,保证落盘文件名与规范形式一致。
  3. 重定向与规范化规则。把非规范形式(如含大写)301 到规范形式,可以让缓存键和源站都只面对一种路径。要注意重定向链不能太长,否则每次请求都要多跳一次,缓存命中判断会变复杂。

一个假设例子:源站规范形式定为全小写,缓存键也按小写生成。请求 /Assets/App.js 时,先被 301 到 /assets/app.js,再由缓存按小写键查找。这样大小写不同的请求最终都收敛到同一份缓存对象。若只改了缓存键、没加重定向,源站仍可能因大小写收到 404,缓存里就会出现一份“命中但内容为空”的记录,反而更难排查。

会使统一映射失效的反例

最需要警惕的反例是:规范形式统一后,原本两个大小写不同、内容也不同的资源被合并。比如 /Config/Prod.json 与 /config/prod.json 分别存放生产与测试配置,内容不同。若只按小写统一映射,两者会命中同一份缓存,其中一个环境的配置会被错误覆盖。判断依据是:统一前后分别对比两个路径的响应体哈希,如果哈希不同却映射到了同一键,说明统一动作选错了对象,应改为保留区分或重命名文件,而不是继续合并。

另一个会让结论失效的条件是:路径差异其实来自 URL 编码或末尾斜杠,而不是字母大小写。这种情况下改大小写规则不会生效,需要先确认差异的真实来源。

下一步动作与验收方式

确认属于大小写映射问题后,可以按以下顺序推进:先选定规范形式并写入构建或部署脚本,让落盘文件名与之一致;再调整缓存键生成规则,使其在比对前做同样的规范化;最后补一条从非规范形式到规范形式的 301,并观察一段时间内 404 与缓存未命中的变化。验收时不要只看“请求量下降”或“抓取量归零”就判定成功,这些现象也可能来自规则误伤或监控口径变化。更可靠的依据是:同一资源的两种大小写写法返回相同的 ETag,且源站日志中非规范路径的 404 数量下降。如果 404 没降反而升,说明重定向或落盘环节还有一处没对齐,应回到三个位置重新核对,而不是继续叠加缓存规则。

图1 图2

nginx