白话http1.0,1.1,2.0,3.0发展

149 阅读4分钟

http1.0针对每次http请求都会建立一个t c p连接来进行数据传输,这种数据传输方式的开销非常大且会拉低响应的速度。所以在http1.1的时候引入了长连接这个协议,每个t c p连接在处理完一次请求后不会被关闭,而是可以供下一次请求复用,在一定程度上解决了多个请求花费在连接建立时间长的问题。但是仍然存在着队头阻塞问题。

队头阻塞问题指的是在多个请求的场景下,当上一个请求的没有得到及时的回应的时候,下一个请求是无法发送的,这是在http层面上的表现形式。那么怎么解决这个问题的呢,真正的解决办法是采用多路复用的方式来发送请求。而http1.1因为一些协议限制是无法引入多路复用这个机制。所以浏览器就为每个页面开了多个t c p连接,一般是6个,每个链接请求都要得到完整的回应后才能进入下一请求。这种解决方式无疑是昂贵的,不可扩展的。所以就有了后面的http2.0。

为什么http1.1中每个请求要等到完整的响应后才能开启下一次请求呢?因为http1.1采用的是文本格式来传输数据,传输的资源块之间是没有分割符的,它只在有效的资源负载前面加了头信息,如果这时候同时返回多个请求的响应数据,而又不清楚每个资源块在何时开始,在何时结束,就无法分清资源块究竟是属于哪个请求。所以就必须完整响应一个请求后才开启下一个请求,如果前面的资源很大,那么自然就会引起队头阻塞问题。

总结一下:http1.0最大的缺陷在于每次请求都要建立新的链接,而t c p可靠链接的建立开销是很大的。而1.1在1.0的基础上引入了长连接,带来的问题是多个请求的阻塞问题。1.1在这个问题是是有一种管道化的解决办法(并发请求,排队响应,仍然会影响其他请求的响应)。因为其本身就具有队头阻塞问题,浏览器直接不支持。最后浏览器的解决办法是开多个t c p链接来处理多个请求。这不算是一种高效,可扩展的解决办法。

http2.0采用的是二进制格式来传输数据,将请求和响应的数据都划分为更小的帧,通过多个帧组成消息流,每个流都有流ID,流存在于连接中的虚拟通道,可以承载双向消息。基于这样的条件,我们就可以将每个请求的响应进行乱序发送,最后可以将其进行顺序组合。这就解决了http1.x中在http层面的队头阻塞问题,这就是多路复用,将同个域名下的所有请求都放在同一个t c p连接中完成。但是t c p层面仍然有队头阻塞问题。体现在2.0中,一个通道中的多个t c p连接,如果其中一个连接丢包,那么整个t c p就会重传,就会阻塞其他的连接。

同时,2.0还进行了头部压缩,将每次请求中的头信息进行压缩,减少了头信息的网络流量。服务端推送:可以在请求一些静态资源的时候主动推送另外的一些资源。但是这些资源仅限静态资源。以上就是2.0在1.1基础上的一些优化,但仍然存在一些问题:本质上t c p建立时间长;解决了http层面的队头阻塞但是t c p层面仍然不能解决;通过四元组的方式建立连接在多变的网络环境下开销很大。

http3.0直接抛弃了传统的t c p协议进行连接,而是采用改造ud p的方式进行。3.0要做的事就是实现前面版本的功能以及解决遗留下来的问题,也就是说用ud p实现t c p的安全机制,以及利用ud p的优势去解决遗留的问题,比如因为ud p在同一个链路上的流相互不影响,所以就自然的解决了队头阻塞这个问题。关于3.0的细节,这里就不做过多的描述,后续有时间再补充吧!