同一个接口,有人看到旧价格,有人却短暂看到另一位用户的资料,问题可能不是源站数据错了,而是缓存把不该共享的响应复用了。处理这类故障,重点是让CDN动态内容缓存绕过条件与配置和接口的真实共享范围一致:公开且可共用的响应才缓存,依赖身份或请求状态的响应应绕过。
先判断误命中发生在哪一层
先选一个受影响请求和一个正常请求,对照状态码、响应正文、响应头及请求参数。查看 CDN 控制台或响应诊断头中的命中状态、缓存年龄等信息;不同服务商的头字段名称并不统一。若请求标记为命中缓存,且源站日志没有对应访问,问题多半在边缘缓存规则;若为未命中仍返回错误,再查源站和应用缓存。
重点核对接口是否按用户、地区、语言、筛选条件或权限返回不同内容。比如公开的商品目录可以多人共享,但根据登录身份返回的收藏状态不能直接共用。只看 URL 一样就判定响应相同,是常见误区。
按响应头设置缓存或绕过
让源站明确表达响应范围
对不应存储的个人资料、账户状态和敏感结果,源站可返回 Cache-Control: private, no-store。对允许边缘缓存的公共响应,可使用 Cache-Control: public 并设置适当的 s-maxage。具体规则须确认 CDN 是否遵循源站头:有些配置会覆盖响应头,不能只修改应用代码后便假设绕过已经生效。
Set-Cookie 的出现不一定会在所有 CDN 配置中自动禁用缓存;反过来,响应没有这个头也不代表内容适合共享。应明确建立绕过规则,而非依赖默认行为。若响应确实会随请求头变化,Vary 应准确列出影响内容的请求头;无关头不要加入,否则会产生大量不同缓存副本。
逐项检查缓存键和绕过规则
缓存键决定哪些请求会被当作同一份内容。检查它是否包含影响响应的查询参数、必要请求头和路径;若忽略了语言参数或筛选条件,彼此不同的结果就可能共用缓存。也不要把所有 Cookie 都塞进键中:这会降低命中率,且不能代替对敏感接口的绕过。

- 在规则清单中确认接口路径、请求方法和优先级,检查是否有宽泛的“缓存所有内容”规则覆盖了例外。
- 将个人资料、订单状态等依赖登录身份的路径设为绕过;对写入或触发操作的请求也不要按普通页面缓存处理。
- 对公开只读接口,逐个核对会改变结果的查询参数和请求头,将它们纳入缓存键,或为该类请求单独绕过。
- 清除受影响路径的旧缓存,再分别用不同用户、参数和语言重复请求,比较正文与响应头。
- 确认公开响应命中、个性化响应绕过后,观察源站负载、缓存命中率和错误反馈;每次只调整一类规则,便于回退。
公共数据与个性化数据要分开
例如天气服务的城市当前状况通常可以按城市共享,但账户中的收藏城市列表属于个人数据。可把公共查询接口设为短时缓存,把账户接口明确绕过,而不是整个站点一律禁用缓存。若数据刷新较频繁,可先从数秒到几十秒的缓存时间评估;可接受时效还取决于源站刷新周期和业务风险,价格、库存等信息不能照搬天气数据的策略。
判断CDN动态内容缓存绕过条件与配置是否正确,不只看命中率,还要验证不同身份是否绝不会拿到彼此的数据。缓存键覆盖所有变化维度,响应头表达清楚共享范围,路径规则再处理例外,三者缺一不可。
常见问题
响应头写了 no-store,为什么仍显示命中?
检查 CDN 是否覆盖源站响应头、缓存规则是否优先级更高,并清除旧对象后复测。
把所有 Cookie 加入缓存键安全吗?
不一定。它可能造成缓存碎片;个性化接口应优先绕过,只对确实影响公共响应的必要字段设计缓存键。
接口没有登录信息,就可以缓存吗?
不能仅凭这一点判断。还要看查询参数、请求头、地区等因素是否改变响应,以及内容是否允许短暂过期。
调整后如何确认误命中已解决?
清理相关缓存,使用不同身份和参数复测正文、命中状态及缓存年龄;同时核对源站日志,确认绕过请求确实到达源站。


