我无法理解当多个请求并行发送时(在获得响应之前)HTTP如何工作。有两种情况:
1)使用Connection: Keep-Alive
。
根据HTTP spec:
支持持久连接的客户端可以“管道化”它 请求(即,发送多个请求而不等待每个请求 响应)。服务器必须将响应发送给那些请求 收到请求的顺序相同。
这种方式似乎很难实现和维护。服务器必须跟踪请求的顺序,并且必须以正确的顺序响应。它不仅可能不容易实现,而且还会受到性能影响:快速请求必须等到处理慢速请求(如果稍后发出)。
此外,如果我们讨论的是负载均衡器,那么代理必须跟踪哪个请求被发送到哪个服务器,因此当它们返回时,它可以将它们放入队列并按顺序响应。那么为什么不首先这样做呢?即客户端放置(例如)ID
标头听起来更自然,更容易,服务器处理请求并使用相同的ID
标头进行响应,以便客户端可以将请求与响应进行匹配。这更容易实现,并且不会引入排队请求的问题(如果有必要,由客户端跟踪请求的顺序)。
所以问题是:以指定方式指定流水线的原因是什么?
2)没有Connection: Keep-Alive
。
我无法找到有关该案例的任何信息。假设客户端发出两个请求A和B.如果没有keep-alive,服务器将在处理请求后关闭连接。这显然引入了竞争条件。那应该怎么做呢?它应该丢弃第二个请求吗?
答案 0 :(得分:3)
1)Keep-Alive:
根据这篇维基百科文章(http://en.wikipedia.org/wiki/HTTP_pipelining),情况正好相反:服务器端的实现实际上非常简单。我相信这个肯定是基于这样的假设,即单个线程用于处理单个连接的所有请求(这当然是设计此机制时的一般情况),因此该线程按顺序处理同一连接上的多个请求(并且由于TCP保证了有序传递,因此响应按照处理它们的顺序自然接收)。今天在非阻塞服务器实现上可能会有所不同。
2)没有Keep-alive:
如果没有keep-alive,你就不会传递请求,所以我没有看到竞争条件。对于请求A和B,您有两个单独的连接,当请求完成时,每个连接都将关闭。
如果客户端尝试在没有keep-alive的情况下管道请求,我相信规范的以下部分适用:
立即承担持久连接和管道的客户端 连接建立后应该准备重试他们的 如果第一次流水线尝试失败,则连接。如果客户这样做 重试,它必须在它知道连接之前没有管道 执着。 客户还必须准备好重新发送他们的请求 服务器在发送所有内容之前关闭连接 相应的回应。
我的解释是服务器必须合法地丢弃第二个请求,并且只响应第一个请求,因为响应是FIFO。客户端重新发送第二个请求。
请记住:这主要是我自己的假设,我希望它们对你有意义!