首页 > 解决方案 > 为什么最后修改时间和内容长度生成的Nginx etag值?

问题描述

Nginx etag 源码

etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
                              r->headers_out.last_modified_time,
                              r->headers_out.content_length_n)
                  - etag->value.data;

r->headers_out.etag = etag;

如果last-modified-time服务器中的文件发生了变化,但文件内容没有更新,那么etag值是否相同?

为什么不是内容哈希etag生成的值?

标签: nginxetaghttp-caching

解决方案


为什么不是内容哈希生成的 etag 值?

除非 nginx 已经记录了原因,否则很难说出原因。

我的猜测是他们这样做是因为它非常快并且只需要固定的时间。计算哈希可能是一项昂贵的操作,所需的时间取决于响应的大小。以简单和速度着称的 nginx 可能并不愿意增加这种开销。

如果服务器中的文件 last-modified-time 发生了变化,但文件内容没有更新,那么 etag 值是否相同?

不,它不会相同,因此必须重新提供文件。结果是比使用基于散列的 得到的响应要慢ETag,但响应是正确的。

这个算法更大的问题是内容可能会改变而内容ETag保持不变,在这种情况下响应将是不正确的。如果文件更改(以保持相同长度的方式)快于一秒的Last-Modified时间精度,则可能会发生这种情况。(理论上,基于散列的方法有同样的问题——也就是说,两个不同的文件有可能产生相同的散列——但是冲突的可能性很小,因此在实践中它不是一个问题。)

所以大概 nginx 权衡了这个权衡——一个更快的响应,但有一点不正确的可能性——并认为它是值得的。


推荐阅读