我一直在读一本书,我对ETag章节有一个特别的疑问。作者说ETag可能会损害性能,你必须对它们进行精细调整或完全禁用它们。
我已经知道ETag是什么并且了解风险,但是很难让ETag正确吗?
我刚刚创建了一个发送ETag的应用程序,其值为响应主体的MD5哈希值。这是一个简单的解决方案,很容易用多种语言实现。
使用响应正文的MD5哈希是否为ETag错误?如果是这样,为什么?
为什么作者(明显超出我的许多数量级)不提出这样一个简单的解决方案?
除非你是作者:),否则最后一个问题很难回答,所以我试图找到使用MD5哈希作为ETag的弱点。
答案 0 :(得分:45)
ETag类似于Last-Modified标头。这是一种由客户决定变更的机制。
可以说,一个只能发生最后修改日期(即同一文本)的ETag符合ETag所需的所有标准。它只需要是表示资源状态的唯一值。在资源的整个域中并不是唯一的,只需在资源中。
现在,从技术上讲,与Last-Modified标头相比,ETag具有“无限”分辨率。 Last-Modified仅以1秒的粒度更改,而ETag可以是次秒。
您既可以实现ETag和Last-Modified,也可以只实现其中一种(当然也可以不使用)。如果您的Last-Modified不够,请考虑使用ETag。
介意,我不会为每个“资源”设置ETag。基本上,我不会将它设置为任何不期望被缓存的东西(特别是动态内容)。在这种情况下没有意义,只是浪费了工作。
编辑:我看到你的编辑,并澄清。
MD5很好。唯一的缺点是一直在计算MD5。例如,在200K PDF文件上运行MD5是很昂贵的。在不期望缓存的资源上运行MD5简直就是浪费(即动态内容)。
诀窍很简单,无论你使用什么机制,它都应该像Last-Modified一样便宜。 Last-Modified通常也是资源的属性,通常访问起来非常便宜。
ETAG应该同样便宜。如果您使用的是MD5,并且可以缓存/存储资源和MD5哈希之间的关联,那么这是一个很好的解决方案。但是,每次需要ETag时重新计算MD5,基本上与使用ETag提高整体服务器性能的想法相反。答案 1 :(得分:7)
我们在instela中使用etags作为动态内容。
我们的策略是在输出结束时生成要发送的内容的md5哈希,如果if-none-match标头存在,我们将标头与生成的哈希进行比较。如果两个值相同,我们发送304代码并在不返回任何内容的情况下进行请求。
确实,我们消耗了一些cpu来散列内容,但最终我们节省了很多带宽。
我们有一个facebook新闻源样式主页,每个用户都有不同的内容。由于新闻源内容每小时仅更改3-4次,因此主页刷新对于客户端来说非常有效。在移动时代,我认为花费更多的CPU时间比花费带宽更好。带宽仍然比CPU贵,对客户来说这是一种更好的体验。
答案 2 :(得分:2)
如果没有读过这本书,我就不能就作者的确切问题发表意见。
但是,ETag的生成应该使得ETag仅在页面发生变化时生成一次。生成网页的MD5哈希会降低服务器的处理能力和时间;如果您有许多客户端连接,它可能会开始导致性能问题。
因此,您需要一种良好的技术来在必要时生成ETags 并在服务器上缓存它们,直到相关页面发生变化。
答案 3 :(得分:0)
我认为带有ETAGS的perceived problem
可能是您的浏览器必须为页面上的每个资源发出并解析(简单和小)请求/响应,以检查etag值是否已更改服务器端。 / p>
我个人发现这些额外的小往返服务器可以接受经常更改的图像,css,javascript(如果浏览器的etag是最新的,服务器不需要重新发送内容),因为该机制使标记'更新很容易'内容。