ETag与Last-Modified有何区别?

话题来源: 解决CDN缓存未命中的排查

说到ETag和Last-Modified的区别,不少开发者可能都有过类似的困惑:这两个缓存验证机制看起来功能相近,为什么HTTP协议要同时保留它们呢?实际上,我在处理CDN缓存问题时,就曾深刻体会到它们各自的适用场景。ETag就像是给资源发的身份证号码,而Last-Modified则更像是一个时间戳记录,这种差异在缓存控制中会产生微妙但关键的影响。

ETag:基于内容的精确验证

ETag的全称是”Entity Tag”,它是服务器为每个资源生成的唯一标识符。我特别喜欢把它比作文件的”数字指纹”——只要文件内容发生哪怕一个字节的变化,ETag就会改变。记得有次处理图片缩略图服务时,我们用MD5哈希值作为ETag值,这样就能确保用户总是能获取到最新的缩略图版本。

Last-Modified:基于时间的轻量级方案

相比之下,Last-Modified就显得”传统”很多。它只记录资源最后修改的时间戳,实现起来确实简单。但这也带来了一个常见痛点:服务器上的文件可能被重写了内容但修改时间没变,或者时区设置导致的时间误差。我就遇到过因为Nginx配置问题,Last-Modified时间比实际修改时间晚了8小时的诡异情况。

实际应用中的选择策略

从性能角度考虑,ETag的计算通常需要读取整个文件内容(比如计算哈希值),而Last-Modified只需要读取文件属性。所以对于大文件服务,很多团队会选择优先使用Last-Modified。但要注意一个细节:一些CDN厂商会对ETag做特殊优化,比如阿里云的CDN就会智能判断ETag的实现方式。

最稳妥的做法其实是两者都用!HTTP规范允许同时发送ETag和Last-Modified头,客户端可以优先使用ETag验证,当ETag不可用时再回退到Last-Modified。这就像给缓存验证上了双保险,既保证了准确性,又兼顾了兼容性。

话说回来,在RESTful API设计中,我越来越倾向于只使用ETag。因为API响应往往是动态生成的,”最后修改时间”这个概念本身就很难准确定义。而ETag可以基于业务逻辑灵活生成,比如使用数据库记录的版本号或者内容的哈希值,反而更符合API场景的需求。

评论