首页 > 其他分享 >HTTP/3,它来了

HTTP/3,它来了

时间:2022-08-17 16:16:47浏览次数:81  
标签:协议 UDP HTTP TCP QUIC 数据包

HTTP 3.0 是 HTTP 协议的第三个主要版本,前两个分别是 HTTP 1.0 和 HTTP 2.0 ,但其实 HTTP 1.1 我认为才是真正的 HTTP 1.0。

如果你对 HTTP 1.1 和 HTTP 2.0 不太了解的话,可以阅读笔者的这两篇文章。

看完这篇HTTP,跟面试官扯皮就没问题了

HTTP 2.0 ,有点炸 !

我们大家知道,HTTP 是应用层协议,应用层产生的数据会通过传输层协议作为载体来传输到互联网上的其他主机中,而其中的载体就是 TCP 协议,这是 HTTP 2 之前的主流模式。

但是随着 TCP 协议的缺点不断暴露出来,新一代的 HTTP 协议 - HTTP 3.0 毅然决然的切断了和 TCP 的联系,转而拥抱了 UDP 协议,这么说不太准确,其实 HTTP 3.0 其实是拥抱了 QUIC 协议,而 QUIC 协议是建立在 UDP 协议基础上的。

HTTP 3.0

HTTP 3.0 于 2022 年 6 月 6 日正式发布,IETF 把 HTTP 3.0 标准制定在了 RFC 9114 中,HTTP 3.0 其实相较于 HTTP 2.0 要比 HTTP 2.0 相较于 HTTP 1.1 的变化来说小很多,最大的提升就在于效率,替换 TCP 协议为 UDP 协议,HTTP 3.0 具有更低的延迟,它的效率甚至要比 HTTP 1.1 快 3 倍以上。

其实每一代 HTTP 协议的不断发展都是建立在上一代 HTTP 的缺点上的,就比如 HTTP 1.0 最大的问题就是传输安全性和不支持持久连接上,针对此出现了 HTTP 1.1 ,引入了 Keep-Alive 机制来保持长链接和 TLS 来保证通信安全性。但此时的 HTTP 协议并发性还做的不够好。

随着网络的不断发展,每个网站所需资源(CSS、JavaScript、图像等)的数量逐年增加,浏览器发现自己在获取和呈现网页时需要越来越多的并发性。但是由于 HTTP 1.1 只能够允许客户端/服务器进行一次 HTTP 请求交换,因此在网络层获得并发性的唯一方法是并行使用多个 TCP 连接到同一个源,不过使用多个 TCP 链接就失去了 keep-Alive 的意义。

然后出现了 SPDY 协议,主要解决 HTTP 1.1 效率不高的问题,包括降低延迟,压缩 header 等等,这些已经被 Chrome 浏览器证明能够产生优化效果,后来 HTTP 2.0 基于 SPDY ,并且引入了 流( Stream )的概念,它允许将不同的 HTTP 交换多路复用到同一个 TCP 连接上,从而达到让浏览器重用 TCP 链接的目的。

image-20220715185929315

TCP 的主要作用是以正确的顺序将整个字节流从一个端点传输到另一个端点,但是当流中的某些数据包丢失时,TCP 需要重新发送这些丢失的数据包,等到丢失的数据包到达对应端点时才能够被 HTTP 处理,这被称为 TCP 的队头阻塞问题。

那么可能就会有人考虑到去修改 TCP 协议,其实这已经是一件不可能完成的任务了。因为 TCP 存在的时间实在太长,已经充斥在各种设备中,并且这个协议是由操作系统实现的,更新起来不大现实。

基于这个原因,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC。

image-20220715191041133

QUIC 协议

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

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

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

image-20220317213125577

对于很多短连接场景,这种握手延迟影响较大,而且无法消除。毕竟 RTT 是人类和效率的终极斗争。

相比之下,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。

image-20220318092115994

比如有一个 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 会按照顺序进行组装,这同时也保证了数据的顺序性。

image-20220318102638665

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

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

我们知道 TCP 的流量控制是通过滑动窗口来实现的,如果你对滑动窗口不太熟悉,你可以看下我写的这篇文章

TCP 基础知识

在文章后面有提到了滑动窗口的一些概念。

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

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

总的来说,QUIC 具有下面这些优势

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

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

QUCI 协议已经被写在了 RFC 9000 中。

原文链接:HTTP/3 ,它来了。

公众号有很多精品文章,推荐大家关注下。

标签:协议,UDP,HTTP,TCP,QUIC,数据包
From: https://www.cnblogs.com/cxuanBlog/p/16595539.html

相关文章

  • http和https
    基本概念HTTP(HyperTextTransferProtocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。简单来说就是一种发布和接收HTML页面的方法,被用于在......
  • http 请求 Cros 跨域问题记录(转)
    前言当发起请求前端所在的域名跟后端所在域名不在同一个Origin,或者前端请求了不在当前域名下的各种资源,都会有跨域问题。跨域问题主要是在资源提供方配置跨域,即后端服......
  • <摘自https://blog.csdn.net/JavaAndLI/article/details/125359786>SQL分页查询的写法
    MySQL的分页实现是使用LIMIT关键字。Oracle的分页是实现主要是基于rownum行号。SQLServer的分页主要使用的关键字是TOP。 具体用法总结如下:本文中的变量名词说明:1,......
  • HTTP请求以及缓存简介
    HTTP的定义:hypertexttransferprotocol超文本传输协议,是一个应用层的协议,是在互联网中传输数据的一个规定,是万维网中数据传输的基础报文:服务器与浏览器之间传输数据的......
  • 前端必备的 HTTP 知识
    HTTP起源HTTP是由蒂姆·伯纳斯-李(TimBerners—Lee)于1989年在欧洲核子研究组织(CERN)所发起其中最著名的是1999年6月公布的RFC2616,定义了HTTP协议中现今广泛使用......
  • HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记
    TL;DR迫于PatchAsJsonAsync方法缺失,我给dotnet/runtime项目贡献了相关的API,可惜要到.NET7才能用上。https://github.com/dotnet/runtime/pull/60672正文同事小......
  • git https://username:password@仓库地址 包含特殊字符
      可以使用转义字符进行转换: Encodethespecialcharactersbyreplacingthemwiththepercentagecharacter(%)followedbythehexadecimalcode. !......
  • netty系列之:netty对http2消息的封装
    目录简介http2消息的结构netty对http2的封装Http2StreamHttp2Frame总结简介无论是什么协议,如果要真正被使用的话,需要将该协议转换成为对应的语言才好真正的进......
  • CVE-2015-1635-HTTP.SYS远程执行代码漏洞(ms15-034)
    CVE-2015-1635-HTTP.SYS远程执行代码漏洞(ms15-034)一、今日目标:复现一个代号为MS15-034的漏洞。二、漏洞描述:在2015年4月安全补丁日,微软发布的众多安全更新中,修复了HTTP......
  • nginx ngx_http_addition_module 模块openresty content_by_lua 不能生效的原因
    nginx的ngx_http_addition_module模块也是一个修改content的好东西,对于openresty我们经常使用content_by_lua阶段处理但是经过分析ngx_http_addition_module源码的......