浏览器原理 29 # HTTP/2:如何提升网络速度?

简介: 浏览器原理 29 # HTTP/2:如何提升网络速度?

说明

浏览器工作原理与实践专栏学习笔记



HTTP/1.1 网络优化策略


最核心的有如下三种方式:


  1. 增加了持久连接;
  2. 浏览器为每个域名最多同时维护 6 个 TCP 持久连接;
  3. 使用 CDN 的实现域名分片机制。


HTTP/1.1 的资源下载方式:

20210601095542291.png

在该图中,引入了 CDN,并同时为每个域名维护 6 个连接,这样就大大减轻了整个资源的下载时间。



HTTP/1.1 的主要问题


HTTP/1.1 的一个核心问题:HTTP/1.1对带宽的利用率却并不理想。


比如常说的 100M 带宽,实际的下载速度能达到 12.5M/S,而采用 HTTP/1.1 时,也许在加载页面资源时最大只能使用到 2.5M/S,很难将 12.5M 全部用满。


这里解释一下12.5M/S 怎么来的?


带宽是指每秒最大能发送或者接收的字节数。

  • 每秒能发送的最大字节数称为上行带宽
  • 每秒能够接收的最大字节数称为下行带宽


看一下几个单位:


   带宽的统计单位是:比特/秒(bps):10M = 10Mbps;

   网速是数据传输的速度,单位是:字节/秒(B/s KB/s MB/s):1MB/s=1024KB/s ;1KB/s=1024B/s

   比特是信息的最小单位:1字节=8比特(1B=8bit或者1B=8b);1字节/秒=8比特/秒(1B/s=8bps)



所谓 100M 带宽,其实是指 100Mbps (兆比特每秒),亦即 100 x 1024 / 8 = 12800KB/s = 12.5 MB/s


但这只是理论上的速度,实际上则要再扣约 12% 的信息头标识等各种控制讯号。


接下来看看导致利用率不理想的原因?


第一个原因:TCP 的慢启动

一旦一个 TCP 连接建立之后,就进入了发送数据状态,刚开始 TCP 协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态,这个过程称为慢启动


慢启动是 TCP 为了减少网络拥塞的一种策略。

但是慢启动会导致一个性能问题:就是关键资源的加载耗时增大,导致首次渲染流程时间变长。


第二个原因:TCP 连接会竞争固定的带宽

假如系统同时建立了多条 TCP 连接,当带宽充足时,每条连接发送或者接收速度会慢慢向上增加;而一旦带宽不足时,这些 TCP 连接又会减慢发送或者接收的速度。


因为多条 TCP 连接之间又不能协商让哪些关键资源优先下载,这样就有可能影响那些关键资源的下载速度。

第三个原因:HTTP/1.1 队头阻塞的问题

在 HTTP/1.1 中使用持久连接时,虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。


那么该如何去解决这些问题呢?



HTTP/2 的多路复用

怎么规避 TCP 的慢启动和 TCP 连接之间的竞争问题?


HTTP/2 的思路就是一个域名只使用一个 TCP 长连接来传输数据,这样整个页面资源的下载过程只需要一次慢启动,同时也避免了多个 TCP 连接竞争带宽所带来的问题。


怎么解决队头阻塞的问题?


HTTP/2 需要实现资源的并行请求,也就是任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器。


HTTP/2 的解决方案可以总结为:一个域名只使用一个 TCP 长连接和消除队头阻塞问题。



多路复用机制

下面该图就是:HTTP/2 最核心、最重要且最具颠覆性的多路复用机制


2021060111132284.png

图中每个请求都有一个对应的 ID,如

  • stream1 表示 index.html 的请求
  • stream2 表示 foo.css 的请求


这样在浏览器端,就可以随时将请求发送给服务器了。而服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容。


   比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么当接收到请求的时候就可以立即把 index.html 和 bar.js 的响应头信息返回给浏览器,然后再将 index.html 和 bar.js 的响应体数据返回给浏览器。


可以随意发送的原因:每份数据都有对应的 ID,浏览器接收到之后,会筛选出相同 ID 的内容,将其拼接为完整的 HTTP 响应数据。


HTTP/2 使用了多路复用技术,可以将请求分成一帧一帧的数据去传输,收到优先级高的请求也可以优先处理关键资源的请求。



多路复用的实现

HTTP/2通过引入二进制分帧层,实现了 HTTP 的多路复用技术。


HTTP/2 协议栈

20210601192713516.png


请求和接收过程:


   浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。

   这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。

   服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。

   然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。

   二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。

   浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求。


TCP连接建立:


20210602144335636.png


TLS握手和HTTP 2.0通信过程:


image.png


二进制分帧层

参考资料:


HTTP 2.0并没有改变HTTP 1.x的语义,只是在应用层使用二进制分帧方式传输。


20210602111030709.png


帧(frame)

最小的通信单位,承载特定类型的数据,包括帧首部、流标识符、优先值和帧净荷等。


20210602111351268.png



在二进制分帧的结构中,头部有8个字节(64Bit),其中有一个字节(8Bit)来标志帧的类型:

HTTP2.0规定了如下帧类型:

DATA: 用于传输HTTP消息体
HEADERS:用户传输关于流的额外的首部字段
PRIORITY: 用户指定或者重新指定引用资源的优先级
RST_STRING: 用于通知流的非正常终止
SETTINGS:用于通知两端通信方式的数据配置
PUSH_PROMISE: 用于发出创建流和服务器引用资源的要约
PING: 用于计算往返时间,执行“活性”检查
GOAWAY: 用于通知对端停止在当前连接的创建流
WINDOW_UPDATE: 用于针对个别流或个别连接实现流量控制
CONTINUATION: 用于继续一系列首部块片段


比如:


   客户端通过发送 HEADERS 帧来创建新流,这个帧包含带有新流ID的公用首部、可选的31位优先级,以及一组HTTP键-值对首部。


   服务器通过发送 PUSH_PROMISE 帧来发起推送流,这个帧与 HEADERS 帧等效,但它包含“要约流ID”,没有优先级。


   创建新流并发送HTTP首部之后,接下来就是利用 DATA 帧发送应用数据。应用数据可以分成多个 DATA 帧,最后一帧要翻转首部的 END_STREAM 字段。


标志位用于不同的帧类型定义特定的消息标志。


比如:DATA帧就可以使用 End Stream: true 表示该条消息通信完毕。流标识位表示帧所属的流ID。优先值用于 HEADERS 帧,表示请求优先级。R表示保留位。


下面是 Wireshark 抓包的一个DATA帧:

20210602112136179.png



消息(message)

   消息是指逻辑上的HTTP消息(请求/响应)。一系列数据帧组成了一个完整的消息。比如一系列DATA帧和一个HEADERS帧组成了请求消息。


流(stream)

   流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。所有HTTP 2. 0 通信都在一个TCP连接上完成, 这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一 或多个帧组成, 这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。



20210602114802713.png



HTTP/2 其他特性


1. 可以设置请求优先级


HTTP消息分解为多个独立帧之后,这些帧可以交错和传输顺序,进一步提升性能。


为了做到这一点,每个流都可以带上31个比特位的优先级标示服务器通过这些优先级的标志来分配资源(CPU、内存、带宽),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。


不过HTTP2.0没有规定优先级的具体算法,那么这种策略就需要开发着自行来解决。



2. 服务器推送


HTTP 2.0增加了服务端推送功能,服务端可以根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。


如下图所示,客户端请求stream 1,/page.html。服务端在返回 stream 1 消息的同时推送了 stream 2(/script.js) 和 stream 4(/style.css)。


20210602143318168.png


这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用。


3. 头部压缩(首部压缩)


HTTP 1.x每一次通信(请求/响应)都会携带首部信息用于描述资源属性。


HTTP 2.0在客户端和服务端之间使用“首部表”来跟踪和存储之前发送的键-值对。首部表在连接过程中始终存在,新增的键-值对会更新到表尾,因此,不需要每次通信都需要再携带首部。

20210602143832434.png


HTTP 2.0使用了首部压缩技术,压缩算法使用 HPACK。可让报头更紧凑,更快速传输,有利于移动网络环境。


注意:HTTP 2.0关注的是首部压缩,而我们常用的gzip等是报文内容(body)的压缩。二者不仅不冲突,且能够一起达到更好的压缩效果。









目录
相关文章
|
10月前
|
机器学习/深度学习 PyTorch TensorFlow
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic,深度学习探索者。深耕TensorFlow与PyTorch,分享框架对比、性能优化与实战经验,助力技术进阶。
|
10月前
|
监控 负载均衡 安全
WebSocket网络编程深度实践:从协议原理到生产级应用
蒋星熠Jaxonic,技术宇宙中的星际旅人,以代码为舟、算法为帆,探索实时通信的无限可能。本文深入解析WebSocket协议原理、工程实践与架构设计,涵盖握手机制、心跳保活、集群部署、安全防护等核心内容,结合代码示例与架构图,助你构建稳定高效的实时应用,在二进制星河中谱写极客诗篇。
WebSocket网络编程深度实践:从协议原理到生产级应用
|
11月前
|
机器学习/深度学习 人工智能 算法
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic带你深入卷积神经网络(CNN)核心技术,从生物启发到数学原理,详解ResNet、注意力机制与模型优化,探索视觉智能的演进之路。
850 11
|
11月前
|
存储 网络协议 算法
从HPACK到多路复用,揭秘HTTP/2如何终结网络拥堵
HTTP/2通过HPACK压缩头部冗余信息,提升传输效率;并利用多路复用技术,在单个TCP连接上并行处理多个请求,避免队头阻塞,显著提升性能。同时支持服务器推送和流优先级设置,优化资源加载体验。
647 7
|
11月前
|
安全 测试技术 虚拟化
VMware-三种网络模式原理
本文介绍了虚拟机三种常见网络模式(桥接模式、NAT模式、仅主机模式)的工作原理与适用场景。桥接模式让虚拟机如同独立设备接入局域网;NAT模式共享主机IP,适合大多数WiFi环境;仅主机模式则构建封闭的内部网络,适用于测试环境。内容简明易懂,便于理解不同模式的优缺点与应用场景。
1480 0
|
11月前
|
机器学习/深度学习 算法 搜索推荐
从零开始构建图注意力网络:GAT算法原理与数值实现详解
本文详细解析了图注意力网络(GAT)的算法原理和实现过程。GAT通过引入注意力机制解决了图卷积网络(GCN)中所有邻居节点贡献相等的局限性,让模型能够自动学习不同邻居的重要性权重。
1721 0
从零开始构建图注意力网络:GAT算法原理与数值实现详解
|
机器学习/深度学习 人工智能 PyTorch
零基础入门CNN:聚AI卷积神经网络核心原理与工业级实战指南
卷积神经网络(CNN)通过局部感知和权值共享两大特性,成为计算机视觉的核心技术。本文详解CNN的卷积操作、架构设计、超参数调优及感受野计算,结合代码示例展示其在图像分类、目标检测等领域的应用价值。
690 7
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
591 61
|
安全 Java 程序员
分析Muduo网络库源码中的TcpServer组件工作原理
简言之,TcpServer 在 Muduo 中的角色,就是一位终极交通指挥员,它利用现代计算机网络的魔法,确保数据如同车辆一般,在信息高速公路上自由、安全、高效地流动。
174 0