HTTP/2、HTTP/3对HTTP/1.1的性能改进和优化

HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

性能上的改进:

  • 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。

  • 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

性能瓶颈:

  • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;

  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;

  • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞

  • 没有请求优先级控制;

  • 请求只能从客户端开始,服务器只能被动响应。

HTTP/2 做了什么优化?

HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。

那 HTTP/2 相比 HTTP/1.1 性能上的改进:

头部压缩

  • HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

二进制格式

  • HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用二进制格式,因为计算机只懂二进制,那收到报文后,无需再将明文报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率

并发传输

  • HTTP/2 就很牛逼了,引出了 Stream 概念,多个 Stream 复用在一条 TCP 连接来解决队头阻塞问题,

  • 从上图可以看到,1 个 TCP 连接包含多个 Stream,Stream 里可以包含 1 个或多个 Message,Message 对应 HTTP/1 中的请求或响应,由 HTTP 头部和包体构成。Message 里包含一条或者多个 Frame,Frame 是 HTTP/2 最小单位,以二进制压缩格式存放 HTTP/1 中的内容(头部和包体)。

  • 针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并行交错地发送请求和响应

    比如下图,服务端并行交错地发送了两个响应: Stream 1 和 Stream 3,这两个 Stream 都是跑在一个 TCP 连接上,客户端收到后,会根据相同的 Stream ID 有序组装成 HTTP 消息。

服务器主动推送资源

  • 服务端不再是被动地响应,可以主动向客户端发送消息。客户端和服务器双方都可以建立 Stream, Stream ID 也是有区别的,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号。

HTTP/2 有什么缺陷?

HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。

        HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。

所以,一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

HTTP/3 做了哪些优化?

HTTP/2 队头阻塞的问题是因为 TCP,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

QUIC 有以下 3 个特点。

  • 无队头阻塞

  • 更快的连接建立

  • 连接迁移 

无队头阻塞

QUIC 协议也有类似 HTTP/2 Stream 与多路复用的概念,也是可以在同一条连接上并发传输多个 Stream,Stream 可以认为就是一条 HTTP 请求。

        QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响。

更快的连接建立

对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。

        HTTP/3 在传输数据前虽然需要 QUIC 协议握手,但是这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商

甚至,在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果。如下图右边部分,HTTP/3 当会话恢复时,有效负载数据与第一个数据包一起发送,可以做到 0-RT

连接迁移

基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。

        那么当移动设备的网络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建立连接。而建立连接的过程包含 TCP 三次握手和 TLS 四次握手的时延,以及 TCP 慢启动的减速过程,给用户的感觉就是网络突然卡顿了一下,因此连接的迁移成本是很高的。

        而 QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

所以, QUIC 是一个在 UDP 之上的 TCP + TLS + HTTP/2 的多路复用的协议。

        QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题,因为有的网络设备是会丢掉 UDP 包的,而 QUIC 是基于 UDP 实现的,那么如果网络设备无法识别这个是 QUIC 包,那么就会当作 UDP包,然后被丢弃。HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738604.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Purple Pi OH鸿蒙开发板7天入门OpenHarmony开源鸿蒙教程【五】

在完成了Purple Pi OH大部分的接口测试之后,紧接着就是一个充满挑战的任务——利用SDK来编译生成我们自己的镜像文件。通过这一过程,不仅能够让你获得一个可在真实硬件上运行的系统镜像,更重要的是,它让你对OpenHarmony系统的构建…

C++中的内存管理方式

一、C内存管理方式简介 C语言中的内存管理方式在C中可以继续使用,但是在有些地方就无能为力,而且使用起来比较麻烦。因此C中引入了自己的内存管理方式,通过new和delete操作符进行动态内存管理。 二、new语法 new可以申请1个或多个空间&…

Android自定义binder实现进程间通信

通过binder建立进程间通信,主要分为两步: 1. 定义一个binder的服务(在androidManifest.xml中声明)接受远端请求。 服务中创建一个binder实例, 在接收到客户端的连接时,向请求方返回回binder的引用。重写Bi…

Qt - 信号和槽

目录 一、信号 二、槽 三、信号和槽的使用 (一) 连接信号和槽 (二) 自定义槽 (三) 通过 Qt Creator生成信号槽代码 (四) 自定义信号 四、带参数的信号和槽 五、信号与槽的断开 六、Qt4版本信号与槽的连接 (一) Qt4版本信号与槽连接的优缺点 一、信号 在 Qt 中&…

【简单模拟】第十二届蓝桥杯省赛第二场C++ B组《特殊年份》(C++)

【题目描述】 今年是 2021 年,2021 这个数字非常特殊,它的千位和十位相等,个位比百位大 1,我们称满足这样条件的年份为特殊年份。 输入 5 个年份,请计算这里面有多少个特殊年份。 【输入格式】 输入 5 行&#xff…

​Ubuntu20.04 创建新的用户​

1、了解Linux目录结构 推荐看一下:https://www.runoob.com/linux/linux-system-contents.html Linux支持多个用户进行操作的,这样提高了系统的安全性,也可以多人共用一个系统,不过要注意的是系统中安装的软件相关路径&#xff0…

CubeMX使用教程(5)——定时器PWM输出

本篇我们将利用CubeMX产生频率固定、占空比可调的两路PWM信号输出 例如PA6引脚输出100Hz的PWM;PA7引脚输出500Hz的PWM,双路同时输出 我们还是利用上一章定时器中断的工程进行学习,这样比较方便 首先打开CubeMX对PA6、PA7进行GPIO配置 注&a…

Mixamo动画素材导入UE5的最简单方法

一、Mixamo素材 官网:https://www.mixamo.com/ Mixamo是Adobe公司出品的免费动画库,可商用。软件分为characters(角色)、Animations(动画)两个部分。 二、辅助工具MIXAMO CONVERTER 官网:https://terribilisstudio…

Android中MultiDex优化

MultiDex基本思路 当一个Dex文件太肥的时候(方法数目太多、文件太大),在打包或在安装或运行apk也会出问题。 解决方法就是将这个硕大的Dex文件拆分成若干个小的Dex文件。 刚好一个ClassLoader可以有多个DexFile。 MultiDex主要性能瓶颈 解压缩和Dex优化(…

架构师面试问与答

你如何评估和选择合适的分布式缓存方案以提高系统性能? 我会考虑使用分布式缓存系统,如Redis、Memcached等,并根据系统需求和负载情况选择合适的缓存方案。 请简要描述一下你对服务发现和服务注册的理解以及在软件架构中的应用。 服务发现和…

SplitFunctions (BOLT) - 优化阅读笔记

将函数拆分成更小的代码片段,从而执行更激进的代码段重排的优化 在文件 bolt/lib/Passes/SplitFunctions.cpp 相关选项释义默认-split-all-cold尽可能多的分离冷的基本块false-split-align-threshold对齐参数2-split-functions主要功能选项, 分离函数到代码片段fa…

Codeql复现CVE-2018-11776学习笔记

基本使用 1、首先下载struts2漏洞版本源码: https://codeload.github.com/apache/struts/zip/refs/tags/STRUTS_2_3_20 2、构建codeql数据库(构建失败文末有解决办法): codeql database create ~/CodeQL/databases/struts2-2.3.…

C#与WPF通用类库

个人集成封装,仓库已公开 NetHelper 集成了一些常用的方法; 如通用的缓存静态操作类、常用的Wpf的ValueConverters、内置的委托类型、通用的反射加载dll操作类、Wpf的ViewModel、Command、Navigation、Messenger、部分常用UserControls(可绑定的Passwo…

通信总线协议之CAN-FD协议详解

文章目录 通信总线之CAN-FD总线协议详解1. CAN-FD 简介1.1 什么是CAN FD1.2 CAN FD的特点 2. CAN-FD总线协议2.1 帧起始2.2 仲裁段2.3 控制段2.4 数据段2.5 CRC段2.6 ACK段2.7 帧结束 3. 如何从传统的CAN升级到CAN FD 通信总线之CAN-FD总线协议详解 1. CAN-FD 简介 1.1 什么是…

selenium高级应用

常见控件应用 复杂的控件操作1.操作Ajax选项2.滑动滑块操作 WebDriver的特殊操作元素class值包含空格property、attribute、text的区别定位动态id 截图功能页面截图页面截图,返回截图的二进制数据页面截图,返回base64的字符串截取指定元素。先定位元素&a…

Vue3:toRef和toRefs的用法

一、情景说明 我们知道,Vue3中想要定义对象类型的响应式数据 可以通过reactive函数实现 如果,后端返回的对象,有很多的字段,我们想进行结构化赋值 但是,又想保证赋值后的变量也是响应式数据 那么,这个时候…

算法进阶之路:十大经典排序算法详解与实践

算法进阶之路:十大经典排序算法详解与实践 在计算机科学的世界里,排序算法是基础且至关重要的一环。无论是数据库查询、数据分析还是日常的编程任务,高效的排序算法都能显著提升程序的性能。本文将带你深入了解十大经典排序算法,…

BeyondCompared4提示“缺少评估信息或损坏”修复

BeyondCompared4提示“缺少评估信息或损坏”修复 使用 beyond compare4,在安装的30天后,出现“缺少评估信息”、“评估信息损坏”的提示 解决方法如下(Win11下亲测可行) 按 WinR 进入 打开Windows命令运行框,输入cmd …

Redis常见数据类型下

目录 Hash 哈希 常用指令 HSET HGET HEXISTS HDEL HKEYS HVALS HGETALL HMGET 内部编码 Hash类型和关系型数据库 缓存方式对比 List 列表 特点 常用命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP / RPOP LINDEX LINSERT 阻塞(BLOCK)版…

无人机避障技术

无人机避障技术是现代无人机系统发展的重要组成部分,其核心目标是提升无人机的自主飞行能力,确保其在复杂环境中的安全性。本文将详细介绍无人机避障项目的背景、技术原理、实现过程、应用前景以及面临的挑战,以期为读者提供全面而深入的了解…