2014-02-11 46 views
12

我很难理解当多个请求并行发送(获取响应之前)时HTTP如何工作。有两种情况:在获得响应之前发出多个请求

1)与Connection: Keep-Alive

根据HTTP spec

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

这种方式似乎很难实施和维护。服务器必须跟踪请求的顺序,并且必须以正确的顺序响应。不仅实现起来可能并不容易,而且还会带来性能上的提升:快速请求必须等到处理缓慢的请求时才会处理,如果这些请求稍后发出的话。

另外,如果我们正在讨论负载平衡器,那么代理必须跟踪哪个请求被发送到哪个服务器,所以当他们回来时它可以将它们放入队列并按顺序响应。那么为什么不首先这样做呢?即听起来更自然也更容易,客户端放置(例如)ID标题,服务器处理请求并响应相同的ID标题,以便客户端可以将请求与响应匹配。这实现起来更容易,并且不会引起排队请求的问题(如果需要的话,由客户端来跟踪请求的顺序)。

所以问题是:指定流水线的原因是什么?

2)没有Connection: Keep-Alive

我找不到任何有关该案例的信息。假设客户端发出两个请求A和B.如果没有保持活动状态,服务器将在处理请求后关闭连接。这显然引入了竞争条件。那么它应该如何表现?它应该放弃第二个请求吗?

回答

3

1)在保持活动:

根据这个维基百科文章(http://en.wikipedia.org/wiki/HTTP_pipelining)这是相反的:实现在服务器端,其实很简单。我相信这个肯定是基于这样的假设:一个线程用于处理单个连接的所有请求(这当然是设计此机制时的一般情况),因此,该线程按顺序处理同一连接上的多个请求(并且由于TCP保证有序交付,响应自然是按照它们处理的相同顺序接收的)。今天在非阻塞服务器实现上可能会有所不同。

2)在不保活:

不保活,你不这样做管道的要求,所以我没有看到比赛的条件。请求A和B有两个单独的连接,每个连接在请求完成时关闭。

如果客户试图管道请求,而不保持活跃,我认为规范的以下部分适用:

客户即假定持久连接和连接建立后,管道随即 应当准备重新执行如果第一个流水线尝试失败,则连接 。如果客户端执行重试操作,则在它知道持续连接为 之前,它不得进行流水线操作。 如果服务器在发送所有 相应的响应之前关闭了连接,则客户端还必须准备好重新发送它们的请求。

我的理解是服务器必须合法地丢弃第二个请求,并且只响应第一个请求,因为响应是FIFO。客户端重新发送第二个请求。

请记住:这主要是我的想法,我希望他们对你有意义!

+0

感谢您的回复。 ** 1)**但在HTTP1.1中正式添加了keep-alive。 1999年不是吗?协议的设计者应该已经意识到异步服务器。但我可能是错的。 ** 2)**如果客户端打开单独的连接,则您有单独的连接。当客户通过同一连接发出两个请求时,我正在谈论一种不正常的情况。应该如何处理? – freakish

+0

我对时间表不太确定,但1999年对于非阻塞服务器来说似乎相当早。我为2)添加了一些细节, –

+0

这听起来很合理。我会接受这个答案。 :) – freakish