Chrome环境下GET请求交替返回200/404的HTTP缓存相关问题咨询
根因分析方向
1. 源站协商缓存逻辑实现错误
- 自研服务在处理带
If-None-Match、If-Modified-Since的条件请求时,逻辑分支存在异常:正常流程应该是先校验资源是否存在,存在的前提下再比较ETag/修改时间,决定返回304还是200;当前实现大概率是把校验顺序搞反了,或者资源存在性判断的逻辑和缓存校验逻辑绑定错误,当请求携带缓存校验头时,直接跳过了资源存在性校验就走到了404分支。 - 注意到两次响应的ETag完全一致,但404响应返回的是
text/html类型的错误页,还复用了正常200响应的ETag,说明Jetty服务或者自研服务的ETag生成逻辑存在缺陷,不管返回什么状态码都复用了同一个ETag值,属于明确的实现BUG。
2. 源站负载均衡/多实例部署一致性问题
- 如果自研服务是多实例部署,且未配置会话保持,两次请求可能被转发到了不同的实例:其中一个实例上该资源存在,返回正常200;另一个实例上该资源不存在,返回404。同时多实例之间没有统一的ETag生成规则,导致不存在资源的实例错误复用了存在资源实例的ETag,刚好匹配请求携带的
If-None-Match值,就出现了交替返回的现象。 - 可直接在源站服务器本地用curl反复调用接口测试,跳过负载均衡层,验证是否还有交替返回的问题,就能快速定位是不是多实例不一致导致的。
3. 自研服务的资源生命周期逻辑BUG
- 该资源属于临时生成的动态资源,首次访问后被标记为待删除,第二次访问带缓存校验头时刚好被清理逻辑判断为不存在,清理逻辑执行完又触发了资源重建,就会出现一次200一次404的交替现象。可排查该资源对应的创建、删除逻辑是否和请求的缓存校验头有联动。
快速验证方法
- 用curl不带缓存头反复调用接口10次:如果全部返回200,可确定是条件请求处理逻辑的BUG;如果还是交替返回200/404,就往多实例不一致、资源生命周期逻辑的方向排查。
- 给接口传一个随机的query参数,比如
?test=123,让浏览器不会带上缓存校验头发起请求,观察是否还会出现404,也能辅助验证是不是条件请求逻辑的问题。
内容的提问来源于stack exchange,提问作者badvi93d
相关产品推荐
相关产品推荐

