Deb010b2dd957faa3dc82d2e53597183
聊聊QUIC协议

前面几篇文章我们聊了很多TCP的话题,那就不得不聊一下UDP了。TCP是基于链接的可靠传输,相反,UDP是没有链接的不可靠的传输协议。换句话说,UDP是不保证消息一定送达,也不保证消息有序到达的。表面上看起来UDP是有很多弊端了,好像我们都应该用TCP协议,然而事情总是要辩证地去看的。既然TCP有那么多好处,也一定有不好的地方。比如用了丢包重传、流量控制、拥塞控制等等机制,势必会造成性能开销,牺牲了一些实时性;反之,UDP虽然不可靠,但是却能保证实时性,这对于一些实时性要求高、可靠性要求不那么高的场景就很实用,比如QQ、游戏等。
随着互联网的发展,我们的应用场景越来越多也越来越复杂,这时候肯定需要一个两者兼得的协议,既可以保证消息的可靠性,也能保证实时性。这就是本文要讨论学习的QUIC协议。当然还有其他类似的协议,我们也可以自己去设计这种协议,但是QUIC是Google的一套广为流传的协议,有更多的学习价值。

目录

  1. 概述
  2. 优势
    2.1 建立链接延时低
    2.2 改进的拥塞控制
    2.3 无队头阻塞的多路复用
    2.4 多级别流量控制
    2.5 连接迁移
1.概述

QUIC(Quick Udp Internet Connection,快速UDP网络链接)是由Google提出的使用UDP进行多路并发传输的协议。序言中已经说到这是一个可靠的UDP协议,实际上QUIC还有其他几个优点。我们可以形象地认为:

QUIC = TCP + TLS + HTTP2

也就是说,QUIC不仅具有TCP的可靠性,还由TLS的安全性和HTTP2的并发性。

2.优势

2.1 建立链接延时低

基于TCP协议的建立链接一般需要3次握手,建立TLS链接一般需要4次握手,就算使用了Session resuption也还是需要2次握手。这样建立链接的时候延时多,性能低。QUIC在这一点上做的比较好,可以做到0 RTT,比如下图左边的HTTPS的一次完整握手过程,需要3个RTT,使用Session Resuption也需要2个RTT。右边的QUIC由于建立的UDP基础上,也没有TLS握手过程,只需要 0 个 RTT 就能实现数据发送。

图片来自网络 HTTPs与QUIC建立链接

图片来自网络 HTTPs与QUIC建立链接

2.2 改进的拥塞控制

之前有篇文章专门介绍了TCP的拥塞控制。QUIC协议重新实现了TCP的Cubic拥塞控制算法,但是提供了更丰富的特性,比如:

  • 热插拔性

    热插拔的意思是方便灵活,随时生效、更新和停止,具体地表现为:
    1)可以在应用层实现拥塞控制,不需要操作系统和内核级的支持。这是相对TCP的一个质的提高,因为操作系统和内核的升级与部署成本高,不能快速升级。
    2)即使是单个应用程序的不同连接也能支持配置不同的拥塞控制,能为各个用户提供不同的但又更加精准更加有效的拥塞控制。
    3)应用程序不需要停机和升级就能实现拥塞控制的变更,只需要服务端只需要修改一下配置,reload一下。

    • RTT采样更准确

基于TCP的RTT采样会有误差,一般有两种原因:一是使用了基于字节序号的 Sequence Number 及 Ack 来确认消息的有序到达;二是不考虑Ack Delay时间。具体地说:

1)如果一个TCP的段丢失,那么重传的段Seq Number是和原始的段Seq Number是一样的。那么就很难判断收到的ACK是原始请求的响应还是重传请求的响应。如下左图, 如果算成原始请求的响应,但实际上是重传请求的响应(上图左),会导致采样 RTT 变大;如下右图,如果算成重传请求的响应,但实际上是原始请求的响应,又很容易导致采样 RTT 过小。

图片来自网络 TCP重传歧义

图片来自网络 TCP重传歧义

2)TCP计算RTT是直接用客户端的时间戳,即用客户端接收到ACK的时间戳减去发出请求的时间戳,并没有考虑服务端接收到segment到发送Ack的时间,这个时间可以简称为 Ack Delay。

图片来自网络 Ack Delay时间

图片来自网络 Ack Delay时间

top Created with Sketch.