最近简单研究了HTTP协议的发展历程,对此进行了一些总结。
让我们逐一回顾一下HTTP的版本演进:HTTP/1.0 -> HTTP/1.1 -> HTTP/2.0 -> HTTP/3.0(QUIC)。
HTTP/1.0
HTTP 1.0于1996年首次发布,规定了浏览器与服务器之间只保持短暂的连接。每次浏览器请求都需要与服务器建立一个TCP连接,而在服务器完成请求处理后立即断开TCP连接。然而,这种方式存在缺陷,因为TCP连接的建立需要经历三次握手,导致每次HTTP请求都要重新执行这个繁琐的过程,效率相当低下。
HTTP/1.1
HTTP 1.1于1997年发布,引入了默认的持久连接(Connection: keep-alive),消除了每次HTTP请求都重新建立TCP连接的需求。尽管如此,它并未解决HOL(队头)阻塞问题。HOL阻塞指的是当浏览器允许的并行请求数用完时,后续请求需要等待前面的请求完成。
HTTP/2.0
HTTP 2.0在2015年发布,通过引入多路复用解决了HOL阻塞问题。这一版本将一个TCP连接划分为多个流(Stream),每个流中可以传输多个消息(Message),而每个消息则由多个最小的二进制帧(Frame)组成。通过为每个用户操作分配一个流编号(Stream ID),建立了与服务端之间的TCP通道。这种方式使得客户端的每个请求都可以开始下一次请求,从而解决了应用层的队头阻塞。
不过,尽管HTTP/2.0解决了应用层的队头阻塞问题,传输层(TCP)仍然存在队头阻塞。由于TCP协议的可靠性,即按顺序发送和接收数据,且受到拥塞控制的影响,少量的丢包可能导致整个TCP连接上的所有流被阻塞。
HTTP/3.0
HTTP 3.0的第一个草案于2020年发布,并于2022年6月6日正式成为RFC9114标准。HTTP/3.0摒弃了TCP,采用UDP上的QUIC协议来传输应用层数据,从而消除了传输层的队头阻塞问题。
QUIC使用UDP协议在两个端点之间建立多个独立的流(Stream),这意味着在大多数情况下,一个流的数据包丢失不会对其他流产生影响。这一创新有效地解决了队头阻塞问题,使得HTTP/3.0在性能和效率方面迈出了一大步。
HTTP 3.0 还没有大面积的使用,我能想到的问题只有两个。
第一个是 CN 地区对 UDP 的 QOS 或阻断,尚不清楚后续是否会放宽。
第二个是UDP协议依赖四元组信息,大部分没有公网IPv4的设备都需要经过路由器或防火墙的NAT转换才能和服务端进行通信。NAT 设备无法知道 UDP 连接什么时候断开,因此在删除自身的 NAT记录时可能会导致尚在通信中的 UDP 连接断开。
后面同事和我讲了 QUIC 协议有一个 ConnectionId 之类的东西,就算网络环境飘了,他都可以把连接恢复起来。
我查了一下,专业术语是:Connection Migration,有一个提案:https://datatracker.ietf.org/doc/html/draft-ietf-quic-transport-23#section-9 。
最后附上其他大佬画的一张图。
图片
参考
• https://github.com/ByteByteGoHq/system-design-101