发布时给 app.js 加了 Cache-Control: no-cache,本意是不让浏览器缓存,上线后每次访问都发条件请求,CDN 命中率从 90% 掉到 20%,回源 QPS 翻了一倍。乍看像缓存或者权限的锅,追下去往往不是。
curl -sI https://example.com/static/app.js | grep -iE 'cache-control|etag|x-cache' # 期望 public, max-age=31536000, immutable
追下去是这么回事:no-cache 不是不缓存,是每次使用前要回源验证,缓存照样存,只是多一次往返。要完全不落盘得用 no-store。名字里的 no 容易让人理解反,配错方向就把缓存打成了全量回源。
「no-cache 误用」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。
具体做法是,想保留缓存又要及时更新 用 no-cache 加 ETag;完全不允许存储才写 no-store;静态资源用内容哈希加长 max-age 才是常态做法;改完看 CDN 命中率和 304 比例是否回到高位。
验收就看一点,静态资源重新走长缓存 命中率回到 90% 以上 只有发版换文件名时才回源。
