从 HTTP/1.1 到 HTTP/3,解决了一些旧协议的问题,引入了好用的新功能。

HTTP/1.1

HTTP/1.1 通过在传输层和应用层之间增加 SSL/TSL 解决数据不安全的问题,但它本身还有一些其它的不足。

  • 同一时间,一个连接只能对应一个请求,针对同一个域名,大多数浏览器允许同时最多6个并发请求
  • 只允许客户端主动发起请求,一个请求只能对应一个响应
  • 同一个会话的多次请求中,头信息会被重复传输

针对于以上情况,增加了新的协议 SPDY。

SPDY

SPDY(speedy的缩写),是基于 TCP 的应用层协议,它强制要求使用 SSL/TLS,SPDY 并不用于取代 HTTP,它只是修改了 HTTP 请求与响应的传输方式,只需增加一个 SPDY 层,现有的所有服务端应用均不用做任何修改,SPDY 是 HTTP/2 的前身。

HTTP/2

HTTP/2(类似于HTTP+SPDY,不强制使用SSL,但大部分都会使用SSL)在底层传输做了很多的改进和优化,但在语意上完全与HTTP/1.1兼容,比如请求方法(如GET、POST)、Status Code、各种Headers等都没有改变。

超快的加载速度

HTTP/2测速网站中,可以看到 HTTP/2 和 HTTP/1.1 对比170张32*48像素的小图组合成的大图加载速度的时长对比。那为什么会存在如此大的差异呢,在于HTTP/2在很多方面做了调整。

二进制格式

首先就是 HTTP/2 采用二进制格式传输数据,而非 HTTP/1.1 的文本格式。

多路复用

新的二进制分帧机制改变了客户端与服务器之间交互数据的方式,这里有几个新的概念。

• 流:已建立的连接上的双向字节流。

• 消息:与逻辑消息对应的完整的一系列数据帧。

• 帧:HTTP 2.0 通信的最小单位,每个帧包含帧首部,至少也会标识出当前帧所属的流

每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。

图中包含了同一个连接上多个传输中的数据流:客户端正在向服务器传输一个 DATA 帧(stream 5),与此同时,服务器正向客户端乱序发送 stream 1 和 stream 3 的一系列帧。此时,一个连接上有 3 个请求 / 响应并行交换。

把 HTTP 消息分解为独立的帧,交错发送,然后在另一端重新组装是 HTTP 2.0 重要的一项增强。事实上,这个机制会在整个 Web 技术栈中引发一系列连锁反应, 从而带来巨大的性能提升。

• 并行交错地发送请求,请求之间互不影响

• 并行交错地发送响应,响应之间互不干扰

• 只使用一个连接即可并行发送多个请求和响应

• 消除不必要的延迟,从而减少页面加载的时间

• 不必再为绕过 HTTP 1.x 连接限制而多做很多工作(如image sprites、合并CSS\JS、内嵌CSS\JS\Base64图片、域名分片)

首部压缩

HTTP 的每一次通信都会携带一组首部,用于描述传输的资源及其属性。在 HTTP 1.x 中,这些元数据都是以纯文本形式发送的,通常会给每个请求增加 500~800 字 节的负荷。如果算上 HTTP cookie,增加的负荷通常会达到上千字节。为减少这些开销并提升性能,HTTP 2.0 会压缩首部元数据。

客户端和服务器缓存上一次的请求,只发不同的请求头,静态表储存着常用请求头,动态表是随着新的请求增加新的请求头,客户端和服务器同步保存两张表,一个头信息对应着一个索引,如果请求头存在于索引表中,只需发索引号。

服务器推送

HTTP1 中只允许客户端主动发起请求,一个请求只能对应一个响应,HTTP 2.0 新增的一个新功能,就是服务器可以对一个客户端请求发送多个响应。除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。

Web应用可能存在几十个资源,如果服务器能主动的推送资源给服务器,客户端就不需要分析服务器提供的文档再逐个查找,能减少额外的时间延迟。服务器推送功能在网页中嵌入的CSS、JavaScript 或者嵌入其它资源有应用到。

并且还带来了这些好处

  • 客户端可以缓存推送过来的资源
  • 客户端可以拒绝推送过来的资源
  • 推送资源可以由不同的页面共享
  • 服务器可以按照优先级推送资源

以上都是 HTTP/2 提供的新特性,以解决 HTTP1 的不足,但它自身也存在一些问题。

队头阻塞

请求中如果丢失了一个包,导致后面的请求阻塞,此时会等待丢失的包重发,这是TCP底层决定的。

握手延迟

HTTP2的传输层协议还是使用的TCP,仍然有握手的环节。

RTT(Round Trip Time):往返时延,可以简单理解为通信一来一回的时间,建立连接 一个RTT约100ms 还加上TLS 握手要300ms,仍然需要不少时间。

HTTP/3

为了解决以上问题,于是就有了 HTTP/3,HTTP/3 由 Google 开发,弃用 TCP协议,改为使用基于 UDP 协议的 QUIC 协议实现。

解决队头阻塞

QUIC协议使用的 UDP 协议,直接扔无序的数据过来就行,无需排队等待请求的响应,就不存在队头阻塞的问题。

解决握手延迟

而 UDP 连接无需 "握手",也就没有 "握手延迟" 的问题。

存疑

1、UDP 无需建立连接,如何来保证 "可靠传输" 呢?

UDP 接收数据包,如果丢失也不会重新传递,直接对接应用层 HTTP 协议的话,数据可能不完整,这里在应用层和传输层中还增加了 QUIC 协议,如果丢失了包,会告知对方的 QUIC 层,重新传输丢失的包。也就是说由QUIC来保证"可靠传输",相当于实现了TCP的功能。

2、为何Google不开发一个新的不同于TCP、UDP的传输层协议?

目前世界上的网络设备基本只认TCP、UDP,如果要修改传输层,意味着操作系统的内核也要修改,另外,许多TCP新特性都因缺乏广泛支持而没有得到广泛的部署或使用,因此,要想开发并应用一个新的传输层协议,是极其困难的一件事情。

连接迁移

TCP 基于4要素(源IP、源端口、目标IP、目标端口),切换网络时至少会有一个要素发生变化,导致连接发生变化,当连接发生变化时,如果还使用原来的TCP连接,则会导致连接失败,就得等原来的连接超时后重新建立连接。

所以我们有时候发现切换到一个新网络时,即使新网络状况良好,但内容还是需要加载很久(可能会出现网络异常的情况)。

QUIC的连接不受4要素的影响,当4要素发生变化时,原连接依然维持,QUIC连接不以4要素作为标识,而是使用一组Connection ID(连接ID)来标识一个连接,即使IP或者端口发生变化,只要Connection ID没有变化,那么连接依然可以维持,当设备连接到Wi-Fi时,将进行中的下载从蜂窝网络连接转移到更快速的Wi-Fi连接,当Wi-Fi连接不再可用时,将连接转移到蜂窝网络连接。

总结

  • HTTP/1 存在请求数量受限、服务器无法主动推送消息、头部信息过多的问题
  • HTTP/2 增加二进制数据、多路复用、首部压缩、服务器推送的功能,存在队头阻塞、握手延迟的问题
  • HTTP/3 使用基于 UDP 协议的 QUIC 协议实现,解决队头阻塞、握手延迟的问题,增加连接迁移的特性

以上就是HTTP/2,HTTP/3的相关介绍。更多有关 前端网络协议 的内容可以参考我其它的博文,持续更新中~

参考文献:《Web性能权威指南》

参考视频:《网络协议从入门到底层原理》

随机推荐

  1. boot-admin开源项目中有关后端参数校验的最佳实践

    我们在项目开发中,经常会对一些参数进行校验,比如非空校验.长度校验,以及定制的业务校验规则等,如果使用if/else语句来对请求的每一个参数一一校验,就会出现大量与业务逻辑无关的代码,繁重不堪且繁琐的 ...

  2. js 获取 ajax返回数据及处理

    $.ajax({ url: "http://xiaocui.dgoods.cn/app/index.php?i=5&c=entry&do=check&m=stonef ...

  3. Hibernate 基本操作、懒加载以及缓存

    前言 上一篇咱们介绍了 Hibernate 以及写了一个 Hibernate 的工具类,快速入门体验了一波 Hibernate 的使用,我们只需通过 Session 对象就能实现数据库的操作了. 现在 ...

  4. 2022-09-15:Range模块是跟踪数字范围的模块。 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。 半开区间 [left, right) 表示所有 left <= x < righ

    2022-09-15:Range模块是跟踪数字范围的模块. 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们. 半开区间 [left, right) 表示所有 left <= x < ...

  5. 2021-04-18:给定一个二维数组matrix,里面的值不是1就是0,上、下、左、右相邻的1认为是一片岛,返回matrix中岛的数量。

    2021-04-18:给定一个二维数组matrix,里面的值不是1就是0,上.下.左.右相邻的1认为是一片岛,返回matrix中岛的数量. 福大大 答案2021-04-18: 并查集. 代码用gola ...

  6. SQL Server修改列的数据类型

    ALTER TABLE LJPA001H DROP CONSTRAINT DF_LJPA001H_pa_sex_1 ALTER TABLE LJPA001H ALTER COLUMN pa_sex V ...

  7. Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.

    问题描述 新建表或者修改表varchar字段长度的时候,出现这个错误 Row size too large. The maximum row size for the used table type, ...

  8. 《啊哈C语言——逻辑的挑战》学习笔记

    第一章 梦想启航 第1节 让计算机开口说话 1.基础知识 1)计算机"说话"的两种方式 显示在屏幕上 通过喇叭发出声音 2)计算机"说话"之显示在屏幕上 格式: ...

  9. 在DevExpress中使用BandedGridView表格实现多行表头的处理

    在之前较早随笔中介绍过实现多行表头的处理,通过手工创建字段以及映射数据源字段属性的方式实现,有些客户反映是否可以通过代码方式更方便的创建对应的处理操作,因此本篇随笔继续探讨这个多行表头的处理的操作,使 ...

  10. 2013年蓝桥杯C/C++大学B组省赛真题(翻硬币)

    题目描述: 明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如 ...