【问题标题】:HEAD request performanceHEAD 请求性能
【发布时间】:2013-12-27 14:19:19
【问题描述】:

我们目前正在我们的网络服务器上测试性能,并且在生产服务器和测试服务器之间得到了非常不同的结果。

我们正在进行的测试如下:

  • 下载网站上可用的 RSS 提要 XML
  • 对 XML 提要中存在的所有链接发出 HEAD 请求,以检查 url 是否正确

令人惊讶的是,测试服务器上的平均响应时间约为 15 毫秒,而生产服务器上的相同测量结果为 900 毫秒。由于两台服务器(应该)配置相同,我对这些结果感到非常困惑。

  1. 我认为 .CFM 页面的 HEAD 请求实际上并不涉及 ColdFusion 服务器,而只涉及 IIS,这是否正确?
  2. 如果我的第一点是正确的,我在哪里可以检查 IIS 级别是什么可以在响应时间上产生如此大的差异?

按照我从你们那里收到的建议,我只是尝试在测试 cfm 页面中添加一个日志条目,以查看 CFLog 是否被执行。

令人惊讶的是,对同一个文件的同一个 HEAD 请求会在 prod 中生成一个日志条目。而不是在测试中。显然,test 和 prod 的配置应该不同,但我不知道在哪个级别。

【问题讨论】:

  • 我不太确定你的第一个假设。您是否尝试过 cURL 手动获取页面?您可以使用 -X 选项将 HTTP 谓词设置为 HEAD。为了确定,我会查看每台服务器返回的内容。
  • 我尝试使用 Fiddler。正如预期的那样,响应内容是空的,但关于服务器实际上必须构建响应这一事实的问题仍然存在。
  • 这是我选择的另一个工具!您是否尝试过将
  • “由于两台服务器(应该)配置相同” - 两台服务器的规格也相同吗?数据库服务器是否也具有相同的规格和相同的配置(包括,正如 nosilleg 指出的那样,具有相同的数据)?

标签: coldfusion iis-7.5 coldfusion-8


【解决方案1】:

您的第一个假设是不正确的。必须对HEAD 请求的响应进行编码并且不会自动处理。 HEAD 请求应以与 GET 请求相同的标头信息进行响应,这通常意味着执行与 GET 请求相同的代码,然后在响应中省略消息正文。

来自the HTTP spec, section 9.4

HEAD 方法与 GET 相同,只是服务器不能 在响应中返回消息体。包含的元信息 在响应 HEAD 请求的 HTTP 标头中应该是相同的 响应 GET 请求而发送的信息。这种方法可以 用于获取有关实体隐含的元信息 请求而不传输实体主体本身。这种方法是 通常用于测试超文本链接的有效性、可访问性、 以及最近的修改。

对 HEAD 请求的响应可能是可缓存的,因为 响应中包含的信息可用于更新 以前从该资源缓存的实体。如果新的字段值 表示缓存的实体与当前实体不同(如 将通过 Content-Length、Content-MD5、ETag 或 Last-Modified),那么缓存必须将缓存条目视为陈旧的。

我认为很少看到动态网站、CMS 或框架实际上实现了大部分内容,例如HEAD 响应、有效ETags 等 - 所以通常你会从GETHEAD,包括应该从 HEAD 请求中剥离的消息正文。

我假设您在时差中遇到的情况可归因于服务器之间的内容差异。也就是说,测试服务器可能只有最少的内容,因此比完整内容的生产服务器执行得更快。

【讨论】:

  • "包括执行所有代码" - 它只需要执行设置适当标题所需的内容。
  • @PeterBoughton 这就是为什么句子的其余部分是“为了输出相同的元信息”。所以是的,如果有不影响页面输出的代码,那么它就不需要运行。话虽如此,我实际上想不出我自己的代码在执行HEAD 请求时可能会被剥离,因为如果它不影响输出签名,那么它可能一开始就不应该运行。
  • 但开头是“做一模一样”,这是错误的。整个句子可能需要重写以使其清晰。
  • 至于什么时候不同,对于一个在编辑时计算/存储元数据的CMS,一个头部请求只需要读取相关的元数据,而不是读取/执行整个内容——类似于响应一个If -Modified-Since,它只执行到足以知道是响应 304 还是继续执行完整请求。
  • @PeterBoughton 请注意,我说的是“应该”而不是“必须”。也许您更喜欢我按照规范写“应该”?随意使用部分数据破解响应,但您应该评估更多的实际响应。如果您拒绝阅读句子的结尾,我选择忽略您的抱怨,即句子的开头是错误的。但这都是次要的,因为必须对HEAD 请求的响应进行编码并且不能自动处理,这是问题和答案的症结所在。
【解决方案2】:

我不知道这个问题的答案,但是我拼凑了一些代码来测试它,并且有一些结果。警告:我只使用内部 Tomcat Web 服务器,而且我使用的是 CF10(我注意到您使用的是 CF8)。我不认为他们的这些警告会使我在您的特定情况下的发现无效。

<!--- headMe.cfm --->
<cflog text="hit" file="headMe">


<!--- doHead.cfm --->
<cfhttp method="head" url="http://localhost/headMe.cfm" result="httpResponse" />
<cfdump var="#variables#">

所以我浏览到 doHead.cfm,它执行 headMe.cfm 的 HTTP HEAD。如果实际执行了 headMe.cfm,那么我们将在 headMe.log 中获得一个日志条目。如果不是:没有日志条目。

httpResponse 变量是合法的,符合 HEAD 请求的预期,并且...我得到了日志条目。

所以我的结论是,当接收到 HEAD 请求时,不幸的是所有的 CFML 都实际执行了。我真的不认为它应该是。 HTTP 规范中没有任何内容表明它应该或不应该导致“动态”请求完全执行,但我认为如果不这样做会很好。

无论如何,HTH。

【讨论】:

  • “我真的不认为它应该是。” - 嗯?为什么 CF 应该处理 HEAD 请求?
  • 我没有建议 CF(服务器)不应该处理 HEAD 请求,我的意思是 - 在 99.99% 的情况下,随后的 CFML(代码)与response 来自 HEAD 请求,这一切都执行似乎很遗憾。但是 - 现在我的大脑比以前更好地参与 - 仍然有 0.01% 的时间是一些响应标头来自 CFML 处理,所以它仍然需要完成。我想如果一个人想绕过这一切,那就是在 onRequestStart() 中处理它。
  • @AdamCameron 按照您的想法,我尝试了几乎相同的方法。唯一的区别是我从 Fiddler 调用 HeadMe.cfm 而不是 cfhttp 标签。令人惊讶的是,在 CF8 上,执行 HEAD 请求时不会生成日志条目。因此代码没有被执行。 CF8和CF10有区别吗?待续……
  • @AdamCameron 更令人惊讶。在生产服务器上执行 HEAD 请求时,当测试上的相同请求不运行代码时。一定有某个地方可以控制...
  • 有趣。我这里没有要测试的 CF8,但是要在 @home 上进行测试。如果我有时间,今晚会检查。
猜你喜欢
  • 1970-01-01
  • 2011-12-11
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 2015-06-14
  • 1970-01-01
相关资源
最近更新 更多