从 HTTP 的进化历史讲起,细说使用协议的变迁,了解原因发现问题,解码 QUIC 在 HTTP3 中的支撑作用,共同探讨 HTTP3 的未来。
HTTP、HTTP2 和 HTTP3先和大家来回顾一下 HTTP 的历史,看看 HTTP3 相比 HTTP、HTTP2 都有哪些改进和升级的地方。
HTTP VS HTTP2
多路复用:多路复用时,多文件传输有时只需维护一个 TCP 连接。如果是 HTTP1 协议下,每份资源的传输对应一个 TCP 连接,一般最多只能开启 6 个 TCP 连接来传输多路数据,后续每增加一个新链接就会因为拥堵问题卡死,进而导致整个进程无法运行。因此HTTP/2解决了 HTTP 的队头阻塞问题。
头部压缩和 Server Push:HTTP2 会通过 HPACK 做头部压缩。同时 HTTP2 是二进制协议,在解析上相比基于文本的 HTTP解析效率上有所提升,并且 HTTP2 还增加了 Server Push。
在 TCP 下,依然无法解决延迟问题,比如为防止初始阻塞而引入的慢启动;TCP 队头阻塞,比如由于发生丢包,整个连接涉及的传输数据都需要重传而引起的阻塞。
尽管 HTTP2 相比 HTTP 已经有了改进的地方,但是如果你有 2% 的丢包率,那 HTTP2 在性能上就没有优势了。
上图是造成 TCP 队头拥塞(Head of line blocking)的原因。HTTP2 协议是基于 TCP 的,但是 TCP 本身是无法解决队头拥塞,为什么呢?因为 HTTP2 会把一次传输所有的文件都放在一个 TCP 连接中,只要这个 TCP 中发生一个丢包,连接就必须重新建立,之前所有传输内容进行必须重传,从而造成拥塞。
HTTP3 VS HTTP2
HTTP3 本质不是对 HTTP 协议本身的改进,它主要是集中在如何提高传输效率。上图是相比 HTTP2 而言 HTTP3 提升的点:
HTTP3 使用 stream 进一步扩展了 HTTP2 的多路复用。在 HTTP3 模式下,一般传输多少个文件就会产生对应数量的 stream。当这些文件中的其中一个发生丢包时,你只需要重传丢包文件的对应 stream 即可。
HTTP3 不再是基于 TCP 建立的,而是通过 UDP 建立,在用户空间保证传输的可靠性,相比 TCP,UDP 之上的 QUIC 协议提高了连接建立的速度,降低了延迟。
通过引入 Connection ID,使得 HTTP3 支持连接迁移以及 NAT 的重绑定。
HTTP3 含有一个包括验证、加密、数据及负载的 built-in 的TLS安全机制。
拥塞控制。TCP 是在内核区实现的,而 HTTP3 将拥塞控制移出了内核,通过用户空间来实现。这样做的好处就是不再需要等待内核更新可以实现很方便的进行快速迭代。
头部压缩。HTTP2 使用的 HPACK,HTTP3 更换成了兼容 HPACK 的 QPACK 压缩方案。QPACK 优化了对乱序发送的支持,也优化了压缩率。
为什么选择 QUIC从图上可以看到 QUIC 协议层就实现了可靠的数据传输,拥塞控制,加密,多路数据流。
至于 QUIC 为什么使用了 UDP 的问题,在了解这个之前,我们需要先知道一个事情。频繁的用户态和核心态切换会效率问题。理论上说,将应用层的东西迁移到内核从而提升效率是可行的,但是这么做会影响操作系统的稳定性。另一方面,我们可以选择将这部分内容迁移到用户空间。比如目前流行的 DPDK,当网卡将数据包传输过来时,它是绕过内核在用户空间进行控制和应用。目前又拍云的 DNS 就进行了这样的处理,让又拍云的整体效率提升了5-10 倍。
接下来我们来正式说一下 QUIC 为什么使用了 UDP 的问题,是因为以下几点:
避免 ossification(僵化):QUIC 协议加密负载,也是避免协议僵化一种方式,比如当中间层处理 UDP 数据时,只需要按照数据包的方式去处理即可,不需要去关注内部层的具体信息。
放弃改进 TCP 本身
创新方向:QUIC 是由谷歌提出的,所以 UDP 是以浏览器为出发点,从协议、从浏览器方向来进行创新。
TLS 1.3 Vs TLS 1.2
TLS 1.3 跟 1.2 的一些提升主要有上图几点,大家可以大致看一下:
TLS 1.3 采用了新的加密套件
TLS 1.3 定义了一些新的证书类型以及秘钥交换机制。在 TLS 1.3 你不再需要去特别指定,它可以根据秘钥套件配件进行证书类型的自主推导。
QUIC 存在的问题
接下来说一下 QUIC 目前存在的问题。
首先是因为这些年性能的优化提升都针对 TCP ,使得 UDP 性能没有任何改进。当然随着 QUIC3 的发布,相信后续应该会有相对的投入。