在获得响应之前发出多个请求

15
我不太理解当多个请求同时发送(在收到响应之前)时,HTTP是如何工作的。有两种情况:
1)使用“Connection:Keep-Alive”。
根据HTTP规范
客户端支持持久连接的话可以“管线化”其请求(即,发送多个请求而无需等待每个响应)。服务器必须按照接收到请求的相同顺序发送其响应。
这种方式似乎很难实现和维护。服务器必须跟踪请求的顺序并以正确的顺序响应。不仅可能难以实现,而且会有性能损失:如果稍后发出的请求比较慢,则快速请求必须等待处理完慢速请求后才能得到响应。
如果我们在谈论负载均衡器,那么代理必须跟踪哪个请求被发送到了哪个服务器,以便在它们返回时将它们放入队列并按顺序响应。那么为什么不一开始就这样做呢?也就是说,客户端放置(例如)ID头,服务器处理请求并用相同的ID头响应,以便客户端可以将请求与响应匹配。这样实现起来更容易,而且不会引入请求排队问题(如果有必要,由客户端跟踪请求顺序)。
所以问题是:为什么要以指定的方式指定流水线处理?
2)没有Connection: Keep-Alive
我找不到关于这种情况的任何信息。假设客户端发出两个请求A和B。没有保持活动连接,服务器将在处理请求后关闭连接。这显然会引入竞争条件。那么它应该如何行事?应该放弃第二个请求吗?
1个回答

5

1)使用Keep-Alive:

根据维基百科的一篇文章(http://en.wikipedia.org/wiki/HTTP_pipelining),实际上,服务器端的实现非常简单。我认为这种说法是基于以下假设的:对于单个连接,使用单个线程处理所有请求(当设计该机制时,这确实是一般情况),因此同一连接上的多个请求由此线程依次处理(由于TCP保证有序传递,因此响应自然以处理它们的顺序接收)。在非阻塞服务器实现上可能会有所不同。

2)未使用Keep-Alive:

如果没有使用 Keep-Alive,则不会进行请求的流水线处理,因此我不认为存在竞争条件。对于请求 A 和 B,您需要两个独立的连接,每个连接在请求完成后关闭。

如果客户端尝试在未使用 Keep-Alive 的情况下流水线处理请求,则我认为规范中的以下部分适用:

客户端在建立连接后立即假定持久连接并流水线传输, 应准备好在第一次流水线尝试失败后重试其 连接。如果客户端这样做了, 它必须在知道连接是持久的之前不能进行流水线传输。客户端还必须准备好在 服务器在发送所有相应之前关闭连接时重新发送其请求。

我的解释是,由于响应是FIFO的,因此服务器必须合法地丢弃第二个请求并仅响应第一个请求。重新发送第二个请求取决于客户端。

请注意:这些大多是我假设的内容,希望它们对您有意义!


感谢回复。1) 但是keep-alive在HTTP1.1中被正式添加了。这不是在1999年吗?协议的设计者应该知道异步服务器的存在。虽然我可能错了。 2) 如果客户端打开了不同的连接,那么就会有不同的连接。我说的是当客户端在同一个连接上发出两个请求时,应该如何处理? - freakish
我不确定时间表,但对于非阻塞服务器来说,1999年对我来说似乎相当早。我已经为2)添加了一些细节。 - Pierre Rust
听起来很合理。我会接受那个答案的。 :) - freakish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接