QUIC协议 和 TCP/UDP 协议

目的:熟悉了解 QUIC协议 和 TCP/UDP 协议。

HTTP 协议历史

  1. HTTP 0.9(1991年)只支持get方法不支持请求头
  2. HTTP 1.0(1996年)基本成型,支持请求头、富文本、状态码、缓存、连接无法复用
  3. HTTP 1.1(1999年)支持连接复用、分块发送、断点续传
  4. HTTP 2.0(2015年)二进制分帧传输、多路复用、头部压缩、服务器推送等
  5. HTTP 3.0(2018年)QUIC 于2013年实现、2018年正式更名为HTTP3

HTTP1.0 和 HTTP1.1

  1. 队头阻塞:下个请求必须在前一个请求返回后才能发出,导致带宽无法被充分利用,后续请求被阻塞(HTTP 1.1 尝试使用流水线(Pipelining)技术,但先天 FIFO(先进先出)机制导致当前请求的执行依赖于上一个请求执行的完成,容易引起队头阻塞,并没有从根本上解决问题)
  2. 协议开销大:header里携带的内容过大,且不能压缩,增加了传输的成本
  3. 传输不安全:采用文本形式传输,所有传输的内容都是明文,且客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性
  4. 单向请求:只能单向请求,客户端请求什么,服务器返回什么
  5. HTTP 1.0 和 HTTP 1.1 的区别:
  • HTTP 1.0:仅支持保持短暂的TCP连接(连接无法复用);不支持断点续传;前一个请求响应到达之后下一个请求才能发送,存在队头阻塞
  • HTTP 1.1:默认支持长连接(请求可复用TCP连接);支持断点续传(通过在 Header 设置参数);优化了缓存控制策略;管道化,可以一次发送多个请求,但是响应仍是顺序返回,仍然无法解决队头阻塞的问题;新增错误状态码通知;请求消息和响应消息都支持Host头域

HTTP2

解决 HTTP1 的一些问题,但是解决不了底层 TCP 协议层面上的队头阻塞问题。2015年

  1. 二进制传输:二进制格式传输数据解析起来比文本更高效
  2. 多路复用:重新定义底层 http 语义映射,允许同一个连接上使用请求和响应双向数据流。同一域名只需占用一个 TCP 连接,通过数据流(Stream)以帧为基本协议单位,避免了因频繁创建连接产生的延迟,减少了内存消耗,提升了使用性能,并行请求,且慢的请求或先发送的请求不会阻塞其他请求的返回
  3. Header压缩:减少请求中的冗余数据,降低开销
  4. 服务端可以主动推送:提前给客户端推送必要的资源,这样就可以相对减少一点延迟时间
  5. 流优先级:数据传输优先级可控,使网站可以实现更灵活和强大的页面控制
  6. 可重置:能在不中断 TCP 连接的情况下停止数据的发送

缺点:HTTP 2中,多个请求在一个TCP管道中的,出现了丢包时,HTTP 2的表现反倒不如HTTP 1.1了。因为 TCP 为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP 2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP连接中的所有请求。而对于 HTTP 1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据

HTTP3

HTTP 是建立在 TCP 协议之上,所有 HTTP 协议的瓶颈及其优化技巧都是基于 TCP 协议本身的特性,HTTP2 虽然实现了多路复用,底层 TCP 协议层面上的问题并没有解决(HTTP 2.0 同一域名下只需要使用一个 TCP 连接。但是如果这个连接出现了丢包,会导致整个 TCP 都要开始等待重传,后面的所有数据都被阻塞了),而 HTTP3 的 QUIC 就是为解决 HTTP2 的 TCP 问题而生。

TCP 是什么?

TCP:全称为传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。TCP 是面向连接的、可靠的流协议。

  1. 面向连接(存在三次握手)
  2. 只能进行点对点的数据传输
  3. 面向字节流(TCP 不像 UDP 一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输)
  4. 可靠传输(依靠 TCP 的段编号以及确认序号)
  5. 拥塞控制(网络出现拥塞的时候,TCP 能够减小向网络注入数据的速率和数量,缓解拥塞)
  6. 提供全双工通信(通信双方的应用程序在任何时候都能发送数据)
  7. 存在队头阻塞(使用序列号来标识数据的顺序,数据必须按照顺序处理)

UDP 是什么?

UDP:全称为用户数据报协议,与 TCP 协议一样用于处理数据包,是一种面向无连接不可靠的协议。关注把数据报文传输出去,不关心是否安全到达。

  1. 面向无连接(不需要三次握手)
  2. 支持一对多,多对多,多对一
  3. 不可靠(原因:通信都不需要建立连接、没有拥塞控制所以网络条件不好的情况下可能会导致丢包)
  4. 传输数据高效

QUIC 对比 TCP/UDP 的优缺点

QUIC 协议是 Google 提出的一套基于 UDP 的开源协议,它汇集了 TCPUDP 的优点,传输高效并且可靠。
QUIC 的优点:

  1. 迭代更新快

    TCPUDP 协议是操作系统内核实现的,部署进度慢。QUIC直接基于客户端实现,能实现快速迭代更新

  2. 没有队头阻塞的多路复用

    TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,可能会造成队头阻塞。HTTP2 支持多路复用,但是由于强制使用 TLS,还存在一个 TLS 协议层面的队头阻塞,QUIC 最基本的传输单元是 Packet,不会超过 MTU 的大小,整个加密和认证过程都是基于 Packet 的,不会跨越多个 Packet。这样就能避免 TLS 协议存在的队头阻塞。Stream 之间相互独立,比如 Stream2 丢了一个 Pakcet,不会影响 Stream3 和 Stream4,所以也不存在 TCP 队头阻塞。

  3. 握手更迅速

    TCP需三次握手才能建立连接,有等待时延,如果用了TLS加密,还会进一步增加时延。QUIC采用了类似于TCP Fast Open的设计,在之前已经连接过的情况下可以无需握手,直接开始传送数据,连接建立时延为0

  4. 加密技术比TLS性能好,同时具有各种攻击防御策略。
  5. 前向纠错

    QUICTCP一个主要的核心区别就是:TCP采用 重传 机制,而QUIC采用 纠错 机制。如果发生丢包的话,TCP首先需要一个等待延时来判断发生了丢包,然后再启动重传机制,在此期间会对连接造成一定的阻塞(并且TCP窗口是缓慢增大的,Web这种突发性快速连接情况下窗口会相对较小),从而影响传输时间。而QUIC采用了一种脑洞极大的前向纠错(FEC)方案,类似于RAID5,将N个包的校验和(异或)建立一个单独的数据包发送,这样如果在这N个包中丢了一个包可以直接恢复出来,完全不需要重传,有利于保证高速性,N可以根据网络状况动态调整

  6. 连接保持

    TCP 连接是由四元组标识的(源 IP,源端口,目的 IP,目的端口),当其中一项发生改变,都需要重新建立和服务端的 TCP 连接。QUIC 连接不再以 IP 及端口四元组标识,而是以一个 64 位的随机数作为 ID 来标识,这样就算 IP 或者端口发生变化时,只要 ID 不变,这条连接依然维持着。这就意味着:在IP地址和端口变化的情况下(比如从Wi-Fi切换到流量),可以无需重新建立连接,继续通信

  7. 能实现证书压缩,减少证书传输量,针对包头进行验证等。

QUIC 的不足:

  1. QUIC 基于 UDP ,目前很多网络运营商会降低 UDP 包的优先级,使得 UDP 丢包率特别高
  2. 支持的浏览器少

参考资料:
下一代通信协议:QUIC
科普:QUIC协议原理分析
HTTP/3 都来了,你却还在用 HTTP/1.1?
TCP和UDP比较
一文读懂 HTTP/2 及 HTTP/3 特性
为什么 HTTP1.1 不能实现多路复用
解读HTTP/2与HTTP/3 的新特性