一文领略 HTTP 的前世今生( 四 )


还有 TCP 与 TLS 的叠加握手,增加了延时 。
问题就出在 TCP 身上,所以 Google 就把目光瞄向了 UDP 。
UDP 我们知道是无连接的,不管什么顺序,也不管你什么丢包,而 TCP 我在之前的文章说的很清楚了TCP疑难杂症解析不了解的同学可以去看看 。
简单的说就是 TCP 太无私了,或者说太保守了,现在需要一种更激进的做法 。
那怎么搞? TCP 改不动我就换!然后把 TCP 可靠、有序的功能提到应用层来实现,因此 Google 就研究出了 QUIC 协议 。

一文领略 HTTP 的前世今生

文章插图
 
QUIC 层来实现自己的丢包重传和拥塞控制,还有出于安全的考虑我们都会用 HTTPS,所以需要多次握手 。
一文领略 HTTP 的前世今生

文章插图
 
上面我也已经提到了关于四元组的情况,所以在移动互联网时代这握手的消耗就更加放大了,于是 QUIC 引入了个叫 Connection ID 来标识一个链接,所以切换网络之后可以复用这个连接,达到 0 RTT 就能开始传输 。
一文领略 HTTP 的前世今生

文章插图
 
注意上图是在已经和服务端握过手之后的,由于网络切换等原因才有 0 RTT,也就是 Connection ID 在之前生成过了 。
如果是第一次建连还是需要多次握手的,我们来看一下简化的握手对比图 。
一文领略 HTTP 的前世今生

文章插图
 
所以所谓的 0RTT 是在之前已经建连的情况下 。
当然还有 HTTP/2 提到的 HPACK,这个是依赖 TCP 的可靠、有序传输的,于是 QUIC 得搞了个 QPACK,也采用了静态表、动态表和哈夫曼编码 。
它丰富了 HTTP/2 的静态表,从 61 项加到了 98 项 。
上面提到的动态表,是用来存储未包含在静态表中的头部项,假设动态表还未收到,后面来解头部的时候肯定要被阻塞的 。
所以 QPACK 就另开一条路,在单向的 Stream 里传输动态表的编解码,单向传输好了,接受端到才能开始解码,也就是说还没好你就先别管,防止做一半卡住了 。
那还有前面提到的 TCP 队头阻塞, QUIC 是怎么解决的呢?毕竟它也要保证有序和可靠啊 。
因为 TCP 不认识每个流分别是哪个请求的,所以它只能全部阻塞住,而 QUIC 知道,因此比如请求 A 丢包了,我就把 A 卡住了就行,请求 B 完全可以全部放行,丝毫不受影响 。
【一文领略 HTTP 的前世今生】可以看到基于 UDP 的 QUIC 还是很强大的,而且人家用户多,在 2018 年,互联网标准化组织 IETF 提议将 HTTP over QUIC 更名为 HTTP/3 并获得批准 。
可以看到需求又推动技术的进步,由于 TCP 自身机制的限制,我们的目光已经往 UDP 上靠了,那 TCP 会不会成为历史呢?
我们拭目以待 。
最后今天我们大致过了一遍 HTTP 发展的历史和它的演进之路,可以看到技术是源于需求,需求推动着技术的发展 。
本质上就是人的惰性,只有痛了才会成长 。
而且标准其实也是巨头们为了他们的利益推动的,不过标准确实能减轻对接的开销,统一而方便 。
当然就 HTTP 来说还是有很多内容的,有很多细节,很多算法,比如拿 Connection ID 来说,不同的四元组你如何保证请求一定会转发到之前的服务器上?
所以今天我只是浅显的谈了谈大致的演进,具体的实现还是得靠各位自己摸索,或者之后有机会我再写一些 。
不过相对于这些实现细节我更感兴趣的是历史的演进,这能让我从时代背景等一些约束来得知,为什么这东西一开始是这么设计的,从而更深刻的理解这玩意 。
而且历史还是很有趣的,不是么?


推荐阅读