网易云信 QUIC 应用优化实践

645 阅读8分钟

导读:** 网易云信作为音视频服务提供商的领导者,一直致力于提供顶级的音视频通话服务体验,为用户在各种恶劣环境下提供可靠的音视频服务。如何在极端弱网条件下仍然能给用户提供可靠的音视频服务,是网易云信关注的重中之重。本文将阐述网易云信对于 QUIC 协议的应用优化实践。

引言

QUIC 协议从传输层面相较 TCP 的几点优势

1.png

  • 0-RTT 建连

    QUIC 协议基于 UDP,本身无需握手,并且其使用 Diffie-Hellman 或者 ECC 算法,只在 1-RTT 就完成对等秘钥的协商。QUIC 协议的 0-RTT 建连使用 TLS1.3,通过 early_data 完成加密数据透传。

  • 多路复用/无对头阻塞

    相比于 HTTP/2 的多路复用,QUIC 不会受到队头阻塞的影响,各个流更独立,多路复用的效果也更好。

2.png

  • 连接迁移

与 TCP 用四元组标识一个唯一连接不同,QUIC 使用一个 64 位的 ConnectionID 来标识连接,基于这个特点,QUIC 的使用连接迁移机制,在四元组发生变化时(比如客户端从 WIFI 切换到蜂窝移动网络),尝试“保留”先前的连接,从而维持数据传输不中断。

3.png

  • 可定制的拥塞控制

QUIC 协议没有定义拥塞控制算法的使用,这部分实现在应用层,方便开发者自行优化迭代。

QUIC 协议从协议层面相较 TCP 的几点差别

  • Separate Packet Number Spaces

    QUIC 协议定义了 4 种不同的加密级别,各种加密级别使用不同包序列号空间。\

  • Monotonically Increasing Packet Numbers

    相同包序列号空间中的包序列号单调递增,避免了重传歧义。QUIC 协议的包序列号空间只标识传输顺序,数据包内容的顺序则用 STREAM 帧当中的偏移(offset)来标识。\

  • Clearer Loss Epoch

    当一个 QUIC 包被申明为丢失,QUIC 开启一段丢失检测的周期,在此之后发送的任何一个 QUIC 包被确认则刷新检测周期的时间。与 TCP 不同,TCP 会一直等待序列号空间中的空白被填满尽管有可能在传输过程中相同数据包发生了多次丢失。这样做的意义在于:QUIC 可以更精确地在每个往返时间(RTT)内去更新拥塞窗口的大小。\

  • No Reneging

    不能食言。一旦一个包被对端确认,则改包不能再被申明为丢失。这样的设定大大简化了双端传输协议的设计,也减小了发送端的内存压力。\

  • More ACK Ranges

    相比 TCP 的 SACK 只能确认三个段(范围),QUIC 协议的 ACK 帧支持更多的段(范围)确认。在高丢包场景下,加快了重传恢复的速度,避免零散的范围确认导致的传输中断。\

  • Explicit Correction For Delayed Acknowledgements

    QUIC 协议将计算从接收包到发送该包 ACK 之间的延迟时间,并显式写入 ACK 帧中。这样的设定旨在更加精准地计算网路的往返时间。\

  • Probe Timeout Replaces RTO and TLP

    QUIC 协议使用 PTO(probe timeout)探测超时机制,包含了对端的期望最大确认延时,而不是一个固定的最小超时。与 TCP 的 RTO 超时不同的是,QUIC 协议在 PTO 过期时不会去尝试折叠拥塞窗口,因为尾部数据的丢失并不能表示网路发生了持续的拥塞。发送方可以不受限制地发送更多的数据包在其还有剩余的拥塞窗口的条件下,即便此时已经发生了 PTO 超时。相对于 TCP 的 RTO 机制,PTO 机制更加激进。\

  • The Minimum Congestion Window is Two Packets

    TCP 使用一个数据包作为最小拥塞窗口,如果这个数据包丢失了,意味着需要等待 RTO 来进行重传,这很可能远远大于一个往返时间(RTT),QUIC 协议建议使用两个数据包作为最小拥塞窗口,虽然这样做会增加流量,但是被认为是安全的。

QUIC 协议在网易云信的应用

在网易云信音视频服务的架构中,信令用于 SDP 的交互会话房间的创建 与管理用户信息的上传与下发等,其传输的稳定性和及时性至关重要。传统的 WEBRTC 建议使用 WebSocket 作为信令传输协议,受限于 TCP 协议的缺陷,其在建连时间、传输效率和弱网抗性方面的效果不尽人意。而这些问题直接影响到音视频服务的基线指标,比如首帧时间、链路的稳定性以及弱网抗性等。

云信 QUIC 加速服务设计:

4.png

网易云信使用 QUIC 协议替代 WebSocket 协议进行信令的传输,并在应用和协议层面做了若干优化实践:

  • 多路复用: 根据不同信令的特性,给请求分类分级。对于 Request/Reponse 类型的消息,其可靠性和实时性的要求最高,使用高优先级的 STREAM 进行传输。对于用于链路保活的心跳消息,则使用较低优先级的 STREAM 进行传输。

  • 不可靠的传输拓展: 有一类 Notify 消息类型,不需要接收端进行回复,往往用于广播各端用户的网络状态或者其他信息。其对于实时性的要求很高,但是对可靠性没有很高的要求。对于这种信令,我们可以使用 QUIC 协议的不可靠传输特性进行传输。

    这种特殊的传输使用一种 DATAGRAM 帧,传输这种特殊的帧,需要在 Initial 包中的 CH 模块的 QUIC 传输参数表中进行申明(name=max_datagram_frame_size, value=0x20),用以通告对端对于 DATAGRAM 帧的支持。max_datagram_frame_size 传输参数是一个整数值(表示为可变长度整数),表示端点愿意接收的 DATAGRAM 帧的最大大小(包括帧类型、长度和有效负载),以字节为单位。

    DATAGRAM 帧用于以不可靠的方式传输应用程序数据。帧中的 Type 字段采用 0b0011000X 的形式(或值 0x30 和 0x31),最低有效位是 LEN 位(0x01),表示是否存在 Length 字段:如果该位设置为 0,则 Length 字段不存在,Datagram Data 字段扩展到数据包的结尾;如果该位设置为 1,则存在长度字段。DATAGRAM 帧的结构如下:

5.png

尽管 DATAGRAM 帧在检测到丢失时不会进行重传,但也是需要被 ack 的。\

  • 报文压缩: 云信在传输层引入了 Deflate 算法对 STREAM 帧进行压缩,旨在降低信令传输的带宽占用。

  • 动态的冗余策略: 因为信令非流式数据,FEC 并不能适用于断续数据的传输,以 RTT 和丢包率等指标动态地增加冗余保护对提升传输的弱网抗性也有相当积极的作用。

云信 QUIC 的弱网表现

首屏耗时和登录耗时

6.png

上图是云信音视频业务信令建连使用 TCP 和 QUIC 的对比。在首帧耗时的指标上,QUIC 有 20% 的提升。在登录耗时的指标上,QUIC 有接近 30% 的提升。主要的原因是 QUIC 的建连对比 TCP+TLS 有 2~3 个 RTT 的优化,在高 RTT 的场景下握手时间缩短尤为明显。在直播场景下,云信 QUIC 做了私有化的 0RTT 握手的优化,建连更加快速。

抗丢包性

7.png

上图是云信信令数据在 QUIC 和 TCP 链路下能够抗住的最大丢包率。QUIC 在上行丢包率达到 70% 的条件下仍然可以提供服务,下行边界甚至可以抗住 75% 的丢包。TCP 链路在 45% 的丢包情况下就会出现断开重连。相对于 TCP 的信令链路 QUIC 链路有 50% 的提升。

主要原因:

  • 云信实现了动态冗余,会检测到丢包之后增加冗余度,这样就用冗余包弥补了高丢包,带来了抗丢包性能。
  • QUIC 改进的流量控制和拥塞控制算法让 QUIC 在弱网络下可能取得更大的传输优势。

带限

8.png

我们还做了在带宽受限的情况下,QUIC 对于带宽的使用率,基本上 QUIC 对于带宽的使用率都能达到 90% 以上,然而 TCP 就要差很多。

展望&总结

网易云信在可靠数据加速上可靠数据传输上已经得到很大的提升,但是仍然还有一些需要优化的地方:一旦单向发生丢包,会引起服务器和端都增加双向的冗余度,带来不必要的冗余增加。后续会检测到单向丢包,只针对丢包的链路进行冗余度增加。对于高 RTT 和高丢包场景,QUIC 拥塞控制算法需要持续优化。网易云信将持续在音视频领域,在各种极端情况下为用户提供优质的服务。