【发布时间】:2018-05-10 18:10:27
【问题描述】:
我最近了解了ETag HTTP 标头的概念。 (this) 但是我仍然有一个问题,对于负责生成 ETag 的特定 HTTP 资源?
换句话说,它是实际的应用程序、容器(例如:Tomcat)、Web 服务器/负载均衡器(例如:Apache/Nginx)?
有人可以帮忙吗?
【问题讨论】:
标签: apache rest tomcat nginx etag
我最近了解了ETag HTTP 标头的概念。 (this) 但是我仍然有一个问题,对于负责生成 ETag 的特定 HTTP 资源?
换句话说,它是实际的应用程序、容器(例如:Tomcat)、Web 服务器/负载均衡器(例如:Apache/Nginx)?
有人可以帮忙吗?
【问题讨论】:
标签: apache rest tomcat nginx etag
与 HTTP 规范的大多数方面一样,责任最终在于提供资源的人。
当然,我们经常使用工具(服务器、负载平衡器、应用程序框架等)来帮助我们履行这些职责。但是没有任何规范来定义“Web 服务器”(与应用程序相反)应该提供什么,这只是一个实际问题,即您使用的工具中有哪些功能可用。
现在,特别是查看ETags,一个常见的情况是框架或 Web 服务器可以配置为自动散列响应(正文或其他内容)并将结果放入ETag。然后,在有条件的请求上,它会生成一个响应并对其进行哈希处理以查看它是否已更改,如果没有更改,则自动发送条件响应。
举两个我熟悉的例子,nginx can do this 在 Web 服务器级别使用静态文件,Django can do this 在应用程序级别使用动态响应。
这种方法很常见,易于配置,而且效果很好。但是,在某些情况下,它可能不是最适合您的用例。例如:
ETag 进行比较,您首先必须得到响应。因此,尽管条件响应可以为您节省传输响应的开销,但它不能为您节省生成响应的成本。因此,如果生成响应的成本很高,并且您有 ETags 的替代来源(例如,存储在数据库中的版本号),您可以使用它来获得更好的性能。ETags 到prevent accidental overwrites with state-changing methods,您可能需要添加自己的应用程序代码以使您的比较和设置逻辑具有原子性。因此,在某些情况下,您可能希望在应用程序级别创建 ETags。再次以 Django 为例,它为您提供了一种简单的方法,可以通过provide your own function 计算ETags。
总而言之,为您控制的资源提供ETags 最终是您的责任,但您也可以利用软件堆栈中的工具为您完成这项工作。
【讨论】:
Last-Modified 标头是另一种情况,因此您最好发布一个单独的问题。
网络服务器中使用的典型算法概述。 考虑我们有一个文件
不同的网络服务器返回 ETag 如下:
"5e132e20-417" 即"hex(MTime)-hex(Size)"。不可配置。"42-417-59b782a99f493",即"hex(INode)-hex(Size)-hex(MTime in nanoseconds)"。可以是 configured,但 MTime 无论如何都会是 nanos"417-59b782a99f493" 即"hex(Size)-hex(MTime in nanoseconds)" 即没有 INode,当相同文件在不同服务器上具有不同 INode 时,这对负载平衡很友好。"42-417-5e132e20",即"hex(INode)-hex(Size)-hex(MTime)"。不可配置。W/"1047-1578315296666",即Weak"Size-MTime in milliseconds"。这是incorrect ETag,因为它应该像静态文件一样强大,即八进制兼容性。"hashcode(42-1047-1578315296666771000)" 即INode-Size-MTime,但随后通过哈希码 (dekhash) 简化为简单整数。可以配置,但只能禁用一部分 (etag.use-inode = "disabled")"W/hex(Size)-hex(MTime)"StaticFileServer.calculateETag
一些想法:
MTime(以纳秒为单位)并非在所有平台上都可用,因此不需要这种粒度。MTime-Size 或 Size-MTime 的顺序也很重要,因为 MTime 更可能发生更改,因此在十几个 CPU 周期内比较 ETag 字符串可能会更快。看起来 Nginx 使用了最合理的模式,所以如果你实现尝试使其相同。 用 C 语言生成的整个 ETag 一行:
printf("\"%" PRIx64 "-%" PRIx64 "\"", last_mod, file_size)
我的建议是采用 Nginx 架构并将其设置为 recommended ETag algorithm by W3C。
【讨论】: