为什么Nginx etag是根据last-modified-time和content-length创建的?

问题描述 投票:0回答:1

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值?

nginx etag http-caching
1个回答
5
投票

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

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

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

如果服务器中的文件last-modified-time改变了,但文件内容没有更新,etag值会一样吗?

不,它不会相同,因此必须重新提供文件。结果是比基于哈希的响应慢

ETag
,但响应是正确的。

此算法更大的问题是,内容可能会发生变化,而

ETag
保持不变,在这种情况下,响应将不正确。如果文件更改(以保持相同长度的方式)快于
Last-Modified
时间的一秒精度,则可能会发生这种情况。 (理论上,基于哈希的方法也存在同样的问题,即两个不同的文件有可能产生相同的哈希,但冲突的可能性很小,因此在实践中不必担心。)

因此,nginx 大概权衡了这种权衡——更快的响应,但有轻微的错误机会——并认为这是值得的。

© www.soinside.com 2019 - 2024. All rights reserved.