HTTP 1.1流水线
我必须在Java中实现HTTP客户端,并且对于我的需求,似乎最有效的方法是实现HTTP管道(根据RFC2616 )。
顺便说一句,我想管道POST。 (另外我不是在谈论多路复用。我在谈论流水线操作,即在接收任何响应之前通过一个连接的许多请求 – 批量处理HTTP请求)
我找不到明确声明它支持流水线操作的第三方库。 但我可以使用例如Apache HTTPCore来构建这样的客户端,或者如果必须的话,我自己构建它。
我遇到的问题是,如果这是一个好主意。 我没有找到任何权威的参考资料,HTTP流水线技术不仅仅是理论模型,而是由HTTP服务器正确实现。 此外,所有支持流水线操作的浏览器都默认关闭此function。
所以,我应该尝试实现这样的客户端,否则我将因服务器的实现(或代理)而遇到很多麻烦。 是否有任何参考资料可以为这些提供指导?
如果不知道什么是效率的替代编程模型? 单独的TCP连接?
我已经实现了一个流水线的HTTP客户端。 基本概念听起来很容易,但error handling非常困难。 性能提升是如此微不足道,以至于我们很久以前就放弃了这些概念。
在我看来,它对正常的用例没有意义。 当请求具有逻辑连接时,它只有一些好处。 例如,您有一个3请求事务,您可以批量发送它们。 但通常情况下,如果它们可以流水线化,您可以将它们组合成一个请求。
以下只是我记得的一些障碍,
-
TCP的keepalive不保证持久连接。 如果在连接中有3个管道请求,则服务器会在第一次响应后断开连接。 您应该重试下两个请求。
-
当您有多个连接时,负载平衡也很棘手。 如果没有空闲连接,您可以使用繁忙连接或创建新连接。
-
超时也很棘手。 当一个请求超时时,您必须丢弃所有请求,因为它们必须按顺序返回。
POST不应该是流水线的
8.1.2.2流水线
支持持久连接的客户端可以“管道化”其请求(即,在不等待每个响应的情况下发送多个请求)。 服务器必须按照收到请求的顺序发送对这些请求的响应。
在连接建立后立即采用持久连接和管道的客户端应准备好在第一次流水线尝试失败时重试其连接。 如果客户端进行了这样的重试,它必须在它知道连接是持久的之前才进行管道传输。 如果服务器在发送所有相应的响应之前关闭连接,客户端也必须准备重新发送请求。
客户端不应该使用非幂等方法或非幂等方法序列来管道请求 (参见第9.1.2节)。 否则,提前终止传输连接可能导致不确定的结果。 希望发送非幂等请求的客户端应该等待发送该请求,直到它收到前一个请求的响应状态。
流水线对http服务器几乎没有影响; 他们通常以串行方式处理连接中的请求 – 读取请求,写入响应,然后读取下一个请求……
但客户很可能通过多路复用提高吞吐量。 网站通常有多台具有多个cpu的机器,为什么你要自愿将你的请求限制在一行? 今天它更多的是关于水平可伸缩性(并发请求)。 当然,最好对它进行基准测试。