聊一聊HTTP/3, QUIC 它们是怎么工作的?

为什么我们需要HTTP/3呢?一个重要原因是解决了“头阻塞”问题。

HTTP/2中的头阻塞问题

1f3dd36c5ed07bf1e8e24431d4c2f2ae.png
1*Ta9T4Qr8OodP9JVUgLQvWw.png

HTTP/2通过帧和流在HTTP级别解决了头阻塞问题。但是,在TCP级别问题仍然存在。

在接收来自上层的帧后,TCP会将它们分成段。

如果一切顺利,所有段将到达另一端。

然而,互联网可能不稳定。在这个过程中,一些段可能会丢失。

TCP有一个保证传递的功能。它将接收到的段放入缓冲区,并等待丢失的段重新传输,从而导致头阻塞。

为了解决这个问题,我们需要找到TCP的替代品——QUIC和UDP。

更新的协议栈

d46a1ae066c190a460273145d386c7ef.png
1*uk5OZPL7gtUwqRLwaoGyFw.png

从协议栈中可以看到一个重大的变化:TCP被UDP取代。

不同于TCP,UDP不保证传递,段之间没有依赖关系。这意味着不再会有头阻塞问题。

此外,由于UDP是一种无连接的协议,不需要握手。它运行速度比TCP更快。

在UDP的基础上,引入了一个新协议QUIC。它继承了TCP的一些优点,包括连接管理和流控制。此外,QUIC实现了一些功能来保证数据传递,以弥补UDP的不足。

另一个变化是在QUIC内部实现了TLS,同时继承了其所有安全特性。由于TLS 1.3已经投入生产,QUIC从这个版本开始。

最后但同样重要的是,QPACK取代了HPACK,进一步提高了头部压缩算法的性能。静态表中的条目从61增加到98,并且现在是0索引的。

QUIC数据包、帧和流

QUIC由数据包和帧组成。一个数据包由多个帧组成。

以下是QUIC数据包的结构。

63639331a57e0350da533e16820afd57.png
1*9t-zNhcQq5vcY3xWagvHEg.png

在数据包头中,QUIC使用连接ID来标记其目标和源。

浏览器和服务器可以选择它们的ID。有了它们,我们可以将连接从IP和端口中解耦,实现平稳的连接迁移。

以下情况可能每天都会发生在您身上。

当你离开家时,你的手机会从WiFi切换到4G(很快是5G)。由于IP变化,TCP会重新连接。在重新连接到互联网之前,您将在一瞬间失去连接。

使用QUIC,连接ID保持不变,因此连接在概念上保持不变。尽管IP发生变化,但连接被重用,没有重新连接的成本。

接下来,让我们看一个QUIC数据包的示例。

QUIC IETF

QUIC连接信息

[数据包长度:1350]

1... .... = 头部形式:长头部(1)

.1.. .... = 固定位:True

..00 .... = 数据包类型:初始(0)

.... 00.. = 保留:0

.... ..00 = 包号长度:1字节(0)

版本:draft-29(0xff00001d)

目标连接ID长度:8

目标连接ID:45fb5955dfaa8914

源连接ID长度:0

令牌长度:0

长度:1332

数据包号码:1

负载:5a99e5b29413627619ca3b5add4cf8b6ce348355b1c1a2be9874c7961e7996a24aeec860…

TLSv1.3记录层:握手协议:客户端Hello

填充长度:997

从公共标志1100 0000中,我们可以知道它是一个长头部,其类型是初始的。接下来是QUIC版本:draft-29,然后是目标连接ID及其长度。

接下来,让我们看QUIC帧结构。

1d2619ea3ba29efb624d5e2385d03c8d.png
1*xIZPYaRK_aYglxPs1bEwJQ.png

类似于HTTP/2帧,QUIC中有各种帧类型。

例如,STREAM帧用于携带流,而ACK帧用于控制。

标题中的字段使用可变长度编码,最多可达8字节。

流标识符可以达到2^62,其中两位保留为标记符。

•最不显著的位标记发送方:0表示客户端,1表示服务器。•第二位最

不显著的位标记流的方向:0表示双向流,1表示单向流。

以下是帧的示例。

TLSv1.3记录层:握手协议:客户端Hello

帧类型:CRYPTO(0x0000000000000006)

偏移:0

长度:314

加密数据

握手协议:客户端Hello

帧类型是CRYPTO,这是为握手设计的类型,负载是加密数据。

下面是另一个示例,服务器Hello。

TLSv1.3记录层:握手协议:服务器Hello

帧类型:CRYPTO(0x0000000000000006)

偏移:0

长度:90

加密数据

握手协议:服务器Hello

握手类型:服务器Hello(2)

长度:86

版本:TLS 1.2(0x0303)

随机数:0f58bdbd934450c7aa98242121447bef2fe0733aa5fc3beffab6513c7177f9a4

会话ID长度:0

密码套件:TLS_AES_128_GCM_SHA256(0x1301)

压缩方法:null(0)

扩展长度:46

扩展:key_share(len=36)

扩展:supported_versions(len=2)

除了QUIC帧的新字段外,其余的字段在TLS 1.3握手中都有提到。

HTTP/3协议和帧

QUIC可以完成很多工作,减轻了HTTP/3的工作负担。

例如,与HTTP/2不同,HTTP/3利用QUIC流,而不是自己定义和控制流。

在HTTP/2中管理的大多数帧类型都移到了QUIC,如RST_STREAM帧和WINDOW_UPDATE帧。

由于这一点,HTTP/3的帧结构简化为仅有2个字段——帧类型和长度。

有一点值得一提,HTTP/3没有像HTTPS的443端口一样的指定端口。

浏览器首先使用HTTP/2与服务器建立连接以发现服务。服务器会响应带有Alt-Svc头部的请求,其中包括HTTP/3的端口,例如Alt-Svc: h3-29=":443"。有了这个信息,浏览器异步地连接到该端口。一旦连接建立,将使用HTTP/3进行未来的通信。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小技术君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值