目录

QUIC 协议

前言

HTTP/2.0

QUIC 协议

QUIC 相关资料


QUIC 协议

前言

回顾一下 HTTP 的发展过程。首先,我们想要一种能够在网络上获取文档内容的协议,通过一种叫做 GET 请求的方式进行获取,后来这种 GET 请求被写入了官方文档,HTTP/1.0 应运而生。HTTP/1.0 的出现可以说是颠覆性的,它里面涵盖的一些标准我们目前还仍在使用,例如 HTTP header,协议号的概念,不过,这个版本的 HTTP 还有一 些明显的缺陷,比如它不支持持久性连接,每次请求响应后,都需要断开连接,这样效率很差。没过了多久,制定了 HTTP/1.1 标准,这个标准是互联网上使用最频繁的一个标准,HTTP/1.1 解决了之前不支持持久性连接的缺陷,而且 HTTP/1.1 还增加了缓存和控制模块。

但是,即便 HTTP/1.1 解决了一部分连接性能问题,它的效率仍不是很高,而且 HTTP 还有一个队头阻塞问题。

假如有五个请求被同时发出,如果第一个请求没有处理完成,就会导致后续的请求也无法得到处理,如下图所示

如果第一个请求没有被处理,那么 2 3 4 5 这四个请求会直接阻塞在客户端,等到请求 1 被处理完毕后,才能逐个发出。网络通畅的时候性能影响不大,不过一旦请求 1 因为某些原因没有抵达服务器,或者请求因为网络阻塞没有及时返回,影响的就是所有后续请求,导致后续请求无限阻塞下去,问题就变得比较严重了。

虽然 HTTP/1.1 使用了 pipling 的设计用于解决队头阻塞问题,但是在 pipling 的设计中,每个请求还是按照顺序先发先回,并没有从根本上解决问题。随着协议的不断更新,提出了 HTTP/2.0 。

HTTP/2.0

HTTP/2.0 解决队头阻塞的问题是采用了 stream 和分帧的方式。

HTTP/2.0 会将一个 TCP 连接切分成为多个 stream,每个 stream 都有自己的 stream id,这个 stream 可以是客户端发往服务端,也可以是服务端发往客户端。

HTTP/2.0 还能够将要传输的信息拆分为帧,并对它们进行二进制格式编码。也就是说,HTTP/2.0 会将 Header 头和 Data 数据分别进行拆分,而且拆分之后的二进制格式位于多个 stream 中。下面来看张图。

可以看到,HTTP/2.0 通过这两种机制,将多个请求分到了不同的 stream 中,然后将请求进行分帧,进行二进制传输,每个 stream 可以不用保证顺序乱序发送,到达客户端后,客户端会根据每个 stream 进行重组,而且可以根据优先级来优先处理哪个 stream。

QUIC 协议

虽然 HTTP/2.0 解决了队头阻塞问题,但是每个 HTTP 连接都是由 TCP 进行连接建立和传输的,TCP 协议在处理包时有严格的顺序要求。这也就是说,当某个包切分的 stream 由于某些原因丢失后,服务器不会处理其他 stream,而会优先等待客户端发送丢失的 stream 。举个例子来说,假如有一个请求有三个 stream,其中 stream2 由于某些原因丢失了,那么 stream1 和 stream 2 的处理也会阻塞,只有收到重发的 stream2 之后,服务器才会再次进行处理。

这就是 TCP 连接的症结所在。

QUIC 的小写是 quic,谐音 quick,意思就是。它是 Google 提出来的一个基于 UDP 的传输协议,所以 QUIC 又被叫做快速 UDP 互联网连接

首先 QUIC 的第一个特征就是快,为什么说它快,它到底快在哪呢?

我们大家知道,HTTP 协议在传输层是使用了 TCP 进行报文传输,而且 HTTPS 、HTTP/2.0 还采用了 TLS 协议进行加密,这样就会导致三次握手的连接延迟:即 TCP 三次握手(一次)和 TLS 握手(两次),如下图所示。

对于很多短连接场景,这种握手延迟影响较大,而且无法消除。

相比之下,QUIC 的握手连接更快,因为它使用了 UDP 作为传输层协议,这样能够减少三次握手的时间延迟。而且 QUIC 的加密协议采用了 TLS 协议的最新版本 TLS 1.3,相对之前的 TLS 1.1-1.2,TLS1.3 允许客户端无需等待 TLS 握手完成就开始发送应用程序数据的操作,可以支持1 RTT 和 0 RTT,从而达到快速建立连接的效果。

我们上面还说过,HTTP/2.0 虽然解决了队头阻塞问题,但是其建立的连接还是基于 TCP,无法解决请求阻塞问题。

而 UDP 本身没有建立连接这个概念,并且 QUIC 使用的 stream 之间是相互隔离的,不会阻塞其他 stream 数据的处理,所以使用 UDP 并不会造成队头阻塞。

在 TCP 中,TCP 为了保证数据的可靠性,使用了序号+确认号机制来实现,一旦带有 synchronize sequence number 的包发送到服务器,服务器都会在一定时间内进行响应,如果过了这段时间没有响应,客户端就会重传这个包,直到服务器收到数据包并作出响应为止。

那么 TCP 是如何判断它的重传超时时间呢?

TCP 一般采用的是自适应重传算法,这个超时时间会根据往返时间 RTT 动态调整的。每次客户端都会使用相同的 syn 来判断超时时间,导致这个 RTT 的结果计算的不太准确。

虽然 QUIC 没有使用 TCP 协议,但是它也保证了可靠性,QUIC 实现可靠性的机制是使用了 Packet Number,这个序列号可以认为是 synchronize sequence number 的替代者,这个序列号也是递增的。与 syn 所不同的是,不管服务器有没有接收到数据包,这个 Packet Number 都会 + 1,而 syn 是只有服务器发送 ack 响应之后,syn 才会 + 1。

比如有一个 PN = 10 的数据包在发送的过程中由于某些原因迟迟没到服务器,那么客户端会重传一个 PN = 11 的数据包,经过一段时间后客户端收到 PN = 10 的响应后再回送响应报文,此时的 RTT 就是 PN = 10 这个数据包在网络中的生存时间,这样计算相对比较准确。

虽然 QUIC 保证了数据包的可靠性,但是数据的可靠性是如何保证的呢?

QUIC 引入了一个 stream offset 的概念,一个 stream 可以传输多个 stream offset,每个 stream offset 其实就是一个 PN 标识的数据,即使某个 PN 标识的数据丢失,PN + 1 后,它重传的仍旧是 PN 所标识的数据,等到所有 PN 标识的数据发送到服务器,就会进行重组,以此来保证数据可靠性。到达服务器的 stream offset 会按照顺序进行组装,这同时也保证了数据的顺序性。

众所周知,TCP 协议的具体实现是由操作系统内核来完成的,应用程序只能使用,不能对内核进行修改,随着移动端和越来越多的设备接入互联网,性能逐渐成为一个非常重要的衡量指标。虽然移动网络发展的非常快,但是用户端的更新却非常缓慢,我仍然看见有很多地区很多计算机还仍旧使用 xp 系统,尽管它早已发展了很多年。服务端系统不依赖用户升级,但是由于操作系统升级涉及到底层软件和运行库的更新,所以也比较保守和缓慢。

QUIC 协议的一个重要特点就是可插拔性,能够动态更新和升级,QUIC 在应用层实现了拥塞控制算法,不需要操作系统和内核的支持,遇到拥塞控制算法切换时,只需要在服务器重新加载一边即可,不需要停机和重启。

而 QUIC 也实现了流量控制,QUIC 的流量控制也是使用了窗口更新 window_update,来告诉对端它可以接受的字节数。

TCP 协议头部没有经过加密和认证,所以在传输的过程中很可能被篡改,与之不同的是,QUIC 中的报文头部都是经过认证,报文也经过加密处理。这样只要对 QUIC 的报文有任何修改,接收端都能够及时发现,保证了安全性。

总的来说,QUIC 相比于 HTTP/2.0 来说,具有下面这些优势

  • 使用 UDP 协议,不需要三次连接进行握手,而且也会缩短 TLS 建立连接的时间。
  • 解决了队头阻塞问题
  • 实现动态可插拔,在应用层实现了拥塞控制算法,可以随时切换。
  • 报文头和报文体分别进行认证和加密处理,保障安全性。
  • 连接能够平滑迁移

连接平滑迁移指的是,你的手机或者移动设备在 4G 信号下和 WiFi 等网络情况下切换,不会断线重连,用户甚至无任何感知,能够直接实现平滑的信号切换。

QUIC 相关资料

QUIC 协议比较复杂,想自己完全实现一套对笔者来说还比较困难。

读者有兴趣的话可以先看看开源实现有哪些。

1)Chromium: GitHub - hanpfei/chromium-net

这个是官方支持的。优点自然很多,Google 官方维护基本没有坑,随时可以跟随 chrome 更新到最新版本。不过编译 Chromium 比较麻烦,它有单独的一套编译工具。暂时不建议考虑这个方案。

2)proto-quic:GitHub - google/proto-quic

从 chromium 剥离的一个 QUIC 协议部分,但是其 github 主页已宣布不再支持,仅作实验使用。不建议考虑这个方案。

3)goquic:GitHub - devsisters/goquic: QUIC support for Go

goquic 封装了 libquic 的 go 语言封装,而 libquic 也是从 chromium 剥离的,好几年不维护了,仅支持到 quic-36, goquic 提供一个反向代理,测试发现由于 QUIC 版本太低,最新 chrome 浏览器已无法支持。不建议考虑这个方案。

4)quic-go:GitHub - lucas-clemente/quic-go: A QUIC implementation in pure go

quic-go 是完全用 go 写的 QUIC 协议栈,开发很活跃,已在 Caddy 中使用,MIT 许可,目前看是比较好的方案。

那么,对于中小团队或个人开发者来说,比较推荐的方案是最后一个,即采用 caddy https://github.com/caddyserver/caddy/wiki/QUIC 来部署实现 QUIC。caddy 这个项目本意并不是专门用来实现 QUIC 的,它是用来实现一个免签的 HTTPS web 服务器的(caddy 会自动续签证书)。而QUIC 只是它的一个附属功能(不过现实是——好像用它来实现 QUIC 的人更多)。

从 Github 的技术趋势来说,有关 QUIC 的开源资源越来越多,有兴趣可以自已逐一研究研究:https://github.com/search?q=quic

计算机网络——什么是 QUIC 协议?相关推荐

  1. 利用QUIC协议加速谷歌浏览器对服务器的访问速度【计算机网络】

    文章目录 I.TCP和UDP的两难困境 II.QUIC协议的介绍 III.谷歌浏览器设置步骤 IV.点评QUIC协议 I.TCP和UDP的两难困境 简单科普一下TCP协议和UDP协议,同时引出二者的优 ...

  2. 计算机网络 | 应用层 :HTTP协议详解

    目录 自定制协议 HTTP协议 URL HTTP协议的特点 HTTP协议版本 HTTP协议格式 首行 请求首行 请求方法 响应首行 响应状态码 头部 Cookie与Session 空行 正文 请求正文 ...

  3. 使用QUIC协议实现实时视频直播0卡顿

    一. 视频直播的痛点:卡顿 卡顿是最影响直播体验的因素之一,也是最难解决的问题之一.在流媒体的传输链路中,任何一个环节丢包都可能导致用户观看卡顿. 其中,主播端的推流卡顿最影响观看体验,会直接影响到所 ...

  4. HTTP3.0和QUIC协议那些事

    HTTP3.0和QUIC协议那些事 文章目录 HTTP3.0和QUIC协议那些事 一.HTTP2.0和HTTP3.0 1.1 HTTP2.0和TCP的爱恨纠葛 1.2 谷歌为什么选择UDP 1.3 Q ...

  5. 实战|QUIC协议助力腾讯业务提速30%

    hi ,大家周五好,之前分享过一篇QUIC在蚂蚁金服落地的文章: 实战|QUIC协议在蚂蚁集团落地 今天我们分析一篇,QUIC在腾讯落地的文章,希望大家了解和学习新技术是如何在大厂落地,其中会遇到什么 ...

  6. QUIC协议的演进之路

    当通过网络传输数据时,一种新的协议QUIC(Quick UDP Internet Connection,快速UDP互联网连接)正在成为FAANG的默认选择.本篇文章描述了QUIC协议是如何克服其他版本 ...

  7. 第一章 计算机网络 5 分层结构/协议/接口/服务的概念 [计算机网络笔记]

    第一章 计算机网络 5 分层结构/协议/接口/服务的概念 本笔记参考书目: 计算机网络(第8版)谢希仁 2021王道计算机网络视频公开课 本节重点: 分层结构/协议/接口/服务 实体/对等实体 PCI ...

  8. E百科 | 第2期 扒一扒能加速互联网的QUIC协议

    简介: 众所周知,QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安 ...

  9. 计算机网络中的传输协议是_计算机网络中的传输方式

    计算机网络中的传输协议是 传输方式 (Transmission Modes) The mechanism of transferring data or information between two ...

最新文章

  1. c# 5.0入门经典笔记
  2. [PHP] 遗传算法求函数最大值一般实现
  3. MYSQL中的主表和父表_主表,从表,关联表,父表,子表
  4. css --- 使用scss生成常用的基本css样式
  5. java 拉丁文 unicode_“java语言使用的是Unicode编码”是指的jvm?.java文件?
  6. 6 年大厂面试官,谈谈我对算法岗面试的一些看法
  7. 中国天然蜂蜂蜜市场趋势报告、技术动态创新及市场预测
  8. Windows下部署yolov5实现口罩检测
  9. 华为承诺的鸿蒙系统兑现没有,华为鸿蒙系统遭截胡,安卓12系统率先出手
  10. JAVA常见设计模式面试题
  11. 【转载】Android 中东阿拉伯语适配,看这一篇够了。
  12. mysql朋友圈设计_微信朋友圈技术实现设想
  13. 51驱动AD9833
  14. 关于LANP的相关常识题
  15. git命令将项目克隆到本地
  16. 计算机网络atm功能,自考计算机网络实用技术考核知识点之ATM原理
  17. python双柱状图与双折线图_双坐标实现图标中同时存在柱状图和折线图
  18. 2022.12.23-Python100day-day05-面向对象编程
  19. 键盘记录器的删除方法
  20. vue this.$refs 打印出来是空的原因

热门文章

  1. 竟然34%的孩子有腺样体肥大,保守还是手术?
  2. R6- React高阶组件详解
  3. 基于java的ssm和微信小程序实现物业缴费系统的设计与实现【附项目源码+论文说明】
  4. 内网外网同时使用——双网关设置
  5. 如何用内卷搞垮一个团队?
  6. 2018年 IEEE VIS 科学可视化与体渲染论文整理与分析
  7. 支持向量机(SVM)算法简介
  8. 【题目】了解ffmpeg以及FFmpeg下载安装教程
  9. php echo 跳转链接时
  10. android rsa加密工具类,android RSA加密