6

我必须在 Java 中实现一个 HTTP 客户端,并且根据我的需要,最有效的方法似乎是实现 HTTP 管道(根据RFC2616)。

顺便说一句,我想管道 POST。(另外,我不是在谈论多路复用。我在谈论流水线,即在接收任何响应批处理 HTTP 请求之前通过一个连接进行许多请求)

我找不到明确声明它支持流水线的第三方库。但是我可以使用例如Apache HTTPCore来构建这样的客户端,或者如果我必须自己构建它。

我的问题是这是否是个好主意。我没有找到任何权威参考资料表明 HTTP 流水线不仅仅是一种理论模型,而是由 HTTP 服务器正确实现的。此外,所有支持流水线的浏览器都默认关闭此功能。

所以,我应该尝试实现这样的客户端,否则我会因为服务器的实现(或代理)而遇到很多麻烦。是否有任何参考可以提供这些指导?

如果这是一个坏主意,那么提高效率的替代编程模型是什么?单独的 TCP 连接?

4

3 回答 3

10

POST 不应流水线化

8.1.2.2 流水线

支持持久连接的客户端可以“管道”其请求(即,发送多个请求而不等待每个响应)。服务器必须以与接收请求相同的顺序发送对这些请求的响应。

在连接建立后立即假设持久连接和管道的客户端应该准备好在第一次管道尝试失败时重试他们的连接。如果客户端进行了这样的重试,它必须在知道连接是持久的之前进行管道传输。如果服务器在发送所有相应响应之前关闭连接,客户端也必须准备好重新发送他们的请求。

客户端不应使用非幂等方法或非幂等方法序列对请求进行管道传输(参见第 9.1.2 节)。否则,传输连接的过早终止可能会导致不确定的结果。希望发送非幂等请求的客户端应该等待发送该请求,直到它收到前一个请求的响应状态。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

于 2010-07-21T10:50:46.610 回答
8

我已经实现了一个流水线 HTTP 客户端。基本概念听起来很简单,但错误处理非常困难。性能提升是如此微不足道,以至于我们很久以前就放弃了这些概念。

在我看来,这对正常的用例没有意义。只有当请求具有逻辑连接时,它才有一些好处。例如,您有一个 3 个请求的事务,您可以将它们全部发送。但通常,如果它们可以流水线化,您可以将它们组合成一个请求。

以下只是我记得的一些障碍,

  1. TCP 的 keepalive 不保证持久连接。如果连接中有 3 个请求,服务器会在第一次响应后断开连接。您应该重试接下来的两个请求。

  2. 当您有多个连接时,负载平衡也很棘手。如果没有空闲连接,您可以使用繁忙连接或创建一个新连接。

  3. 超时也很棘手。当一个请求超时时,您必须丢弃所有请求,因为它们必须按顺序返回。

于 2010-07-21T12:27:43.667 回答
-1

流水线对 http 服务器几乎没有影响;他们通常以串行方式处理连接中的请求 - 读取请求,写入响应,然后读取下一个请求......

但是客户端很可能会通过多路复用来提高吞吐量。网站通常有多台机器多cpu,你为什么要自愿限制你的请求到一行?今天更多的是关于水平可伸缩性(并发请求)。当然,最好对其进行基准测试。

于 2010-07-21T21:21:03.323 回答