http HEAD vs GET性能


111

我正在设置一个REST Web服务,该服务只需要尽快回答是或否。

设计HEAD服务似乎是最好的方法,但是我想知道与执行GET请求相比,我是否真的会花些时间。

我想我获得了不要在服务器上打开/关闭主体流的消息(大约1毫秒?)。由于要返回的字节数非常低,因此我可以在传输中获得任何时间的IP数据包号吗?

预先感谢您的回复!

编辑:

为了进一步解释上下文:

  • 我有一组REST服务,用于执行某些进程(如果它们处于活动状态)。
  • 我还有另一个REST服务,指示所有这些第一服务的状态。

由于最后一个服务通常会由大量客户端(通常每5毫秒调用一次)来调用,因此我想知道使用HEAD方法是否可以进行有价值的优化?响应正文中返回大约250个字符。HEAD方法至少获得了这250个字符的传输,但是那有什么影响呢?

我试图对这两种方法(HEAD与GET)之间的差异进行基准测试,运行了1000次调用,但根本看不到增益(<1毫秒)...


2
它还取决于您使用服务器端的方法。通常,可能需要花费相同的服务器时间来处理GET请求或HEAD请求,因为服务器可能需要知道最终的主体才能计算Content-Length标头值,这是HEAD请求响应中的重要信息。除非有其他一些更优化的服务器端方法,否则唯一的好处就是可以节省带宽,并且客户端不必解析响应主体。因此,基本上,优化收益取决于服务器和客户端的实现。
itsjavi

Answers:


173

RESTful URI应该表示服务器上的“资源”。资源通常作为记录存储在数据库或文件系统上的文件中。除非资源很大或在服务器上检索速度很慢,否则使用HEAD代替可能不会看到可衡量的收益GET。检索元数据可能不会比检索整个资源快。

您可以实现这两个选项并对其进行基准测试,以查看哪种方法更快,但是我将专注于设计理想的REST接口,而不是进行微优化。从长远来看,一个干净的REST API通常比可能更快或可能不会更快的笨拙API更具价值。我不反对使用HEAD,只是建议您仅在“正确”的设计时使用它。

如果您真正需要的信息是有关资源的元数据,可以在HTTP标头中很好地表示它,或者检查该资源是否存在,则HEAD可能会很好地工作。

例如,假设您要检查资源123是否存在。A 200表示“是”,而404表示“否”:

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

但是,如果您要从REST服务中获得的“是”或“否”是资源本身而不是元​​数据的一部分,则应使用GET


2
最好的事情总是很简单,就像这个答案一样。瞧!
Afzal SH 2015年

很棒的答案!我有一个问题:如何将其用作touch更新服务器上帖子视图数的命令?帖子数据已通过常规/posts调用检索到,因此我只想在用户以某种方式与帖子交互后更新视图计数。
aalaap

1
@aalaap如果要为HEAD请求更新视图计数器,则也应为请求更新视图计数器GET。决定使用GET还是HEAD最终取决于HTTP客户端。对于这两种请求类型,您的服务器应具有相同的行为方式,但响应时没有响应主体HEAD。至于这是否是实现诸如视图计数器之类的好方法,我不确定。
安德烈D

-1任何可以命名的信息都可以是资源。因此,统一资源定位器。按照设计使用部分HTTP协议的想法是“笨拙的”或“不干净的”。
Fraser

1
@Siddhartha,这通常是正确的,但并非总是如此。Content-Length使用时可以省略Transfer-Encoding: chunked。即使使用Content-Length,服务器也有可能无需获取实际资源即可获取标头中使用的资源大小和其他元数据。甚至元数据甚至可以缓存在内存中以进行快速访问。这些都是特定于实现的。
安德烈D

38

在寻找请求者提出的相同问题时,我找到了此答复。我也在http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html找到了:

HEAD方法与GET相同,除了服务器在响应中不得返回消息正文。响应HEAD请求的HTTP头中包含的元信息应该与响应GET请求发送的信息相同。此方法可用于获取有关请求所隐含的实体的元信息,而无需转移实体主体本身。此方法通常用于测试超文本链接的有效性,可访问性和最新修改。

在我看来,对请求者问题的正确答案是,它取决于REST协议表示的内容。例如,在我的特定情况下,我的REST协议用于检索相当大(超过10K)的图像。如果我不断检查大量此类资源,并且考虑到我使用了请求标头,则按照w3.org的建议使用HEAD请求是有意义的。


14

我强烈反对这种方法。

RESTful服务应遵循HTTP动词语义。GET动词用于检索资源的内容,而HEAD动词将不返回任何内容,并且可以用于例如查看资源是否已更改,了解其大小或类型,检查其是否已被使用。存在,依此类推。

请记住:早期的优化是万恶之源。


8

通过使用HEAD请求而不是GET请求几乎不会改变您的性能。

此外,当您希望它具有REST功能并且要获取数据时,应使用GET请求而不是HEAD请求。


8

GET获取head + body,HEAD仅获取head。哪一个更快,这不应该是个问题。我不理解上面提出的答案。如果您要查找META信息而不是HEAD,则是为此目的。


3

我不了解您对“身体流被打开/关闭”的担心。响应正文将与HTTP响应标头位于相同的流上,并且不会创建第二个连接(顺便说一下,该连接更多地在3-6ms的范围内)。

这似乎是对某些东西的过早优化尝试,而这些东西根本不会产生显着甚至可衡量的变化。真正的区别是与REST的一致性,建议使用GET来获取数据。

我的回答是“否”,如果可以的话,请使用GET,使用HEAD并不会提高性能。


假设内容为100MB。头肯定会小于内容的大小。现在,当您认为我们通过GET或HEAD方法请求该资源时,它们之间没有性能差异吗?
Mohammad Afrashteh '18

3
OP在响应正文中指出了250个字符。不是100MB。完全是另一个问题。
smassey,

1

HEAD请求与GET请求一样,只是响应的主体为空。当您想要的只是有关文件的元数据但不需要传输文件的所有数据时,可以使用这种请求。


-1

您可以轻松地进行一个小的测试来自己衡量性能。我认为性能差异可以忽略不计,因为如果您仅在正文中返回“ Y”或“ N”,则这是在已打开的流后附加的一个额外字节。

我也会选择GET,因为它更正确。您不应该返回HTTP标头中的内容,而只能返回元数据。


GET-它不仅是神秘的“单个额外字节”。只是整个身体!如果是大文件,则可能为数兆字节。
porfirion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.