【转载】http连接

140 阅读3分钟

首先在HTTP 0.9版本中,每次请求都需要新开一个TCP连接,是不可复用的,这非常的消耗性能。

因此在HTTP 1.0版本,引入了Keep-Alive 持久连接的概念,使用Connection: Keep-Alive的首部来操作TCP的持久连接,有效的解决了TCP连接不可复用的问题,减少性能损耗。

但是,他也存在一定的问题,在HTTP 1.0中其实默认的是短链接,没有正式规定 Connection: Keep-Alive 操作,这时HTTP 1.1版本出现了

pipelining 管道技术

对于HTTP 1.1版本,不仅继承了HTTP 1.0的特点,且克服了诸多在HTTP 1.0上的性能问题,不仅正式规定了 Connection: Keep-Alive 的操作,而且通过 pipelining 管道技术实现一次性发送多个请求,以提高吞吐和性能,如下图(ps:在网上找的图),左图为普通长连接的的请求TCP请求过程,右图为通过 pipelining 管道技术实现的一次性发送多个请求。

队头阻塞

然而,pipelining管道技术有队头阻塞问题,即服务器在接收响应时,要求必须按照发送请求的顺序返回。若第一个请求被堵塞了,则后面的请求即使处理完毕了,也需要等待,如下图。

数据分帧

就在这时,光芒照在了HTTP 2.0上,HTTP 2.0 over TCP出现了,它通过数据分帧 — 多个请求复用一个TCP连接(最多6个),然后每个request-response都被拆分成若干个frame帧发送,这样即使一个请求被阻塞了,也不会影响其他请求,如下图,其实它只解决了一部分问题~

ps:如果队头阻塞的粒度是http request级别,那么HTTP/2 over TCP的确解决了HTTP 1.1中的问题。但是在HTTP 2.0 over TCP版本都是基于TCP实现。因此,HTTP 2.0 over TCP并没有解决数据传输层的队头阻塞问题。

如上图所示,当第一个数据包发生丢包的时候,TCP协议会发生阻塞会进行数据重传。虽然TCP有快速重传等机制来缓解这个问题,但是只能缓解,无法完全避免

那么如何解决传输层的队头阻塞问题呢?

因为应用层无法解决传输层的问题,因此需要重新设计和实现传输层,接下来我们看看Google横空出世的HTTP 2.0 over QUIC怎么解决这个问题。

UDP

HTTP 2.0 over QUIC也可以称为HTTP 3.0,它使用UDP实现了一个可靠的多路复用传输层。我们所知的UDP是面向数据报文的,数据包之间没有约束(这也带来了一定的安全性问题,详见UDP协议及其安全隐患),QUIC就是充分利用这个特性解决传输层的队头阻塞问题的。当然,QUIC的协议实现有非常多的细节,而这方面Google确实做得非常好,如果你想进一步了解,可以关注他们的开源实现

小结

1、HTTP 0.9版本,TCP不可复用,耗性能。

2、HTTP 1.0版本,引入Keep-Alive概念,实为短连接,未正名。

3、HTTP 1.1版本,为长连接,正名Keep-Alive,引入pipelining 管道技术,但有队头阻塞问题。

4、HTTP 2.0 over TCP版本,启用数据分帧,只解决粒度级别为http request的队头阻塞。

5、HTTP 2.0 over QUIC即HTTP 3.0版本,启用UDP协议真正的解决传输层的队头阻塞问题。