浏览器原理学习笔记06—浏览器中的网络
Write By CS逍遥剑仙
我的主页: www.csxiaoyao.com
GitHub: github.com/csxiaoyaojianxian
Email: [email protected]
1. HTTP 发展
1.1 HTTP/0.9
1991 年提出的用于学术交流的 HTTP超文本传输协议,基于 TCP 协议,只用来传输体积很小的 HTML 文件。因为需求简单,所以只有一个请求行,没有 HTTP 请求头和请求体;服务器也没有返回头信息;返回的 HTML 格式文件内容以 ASCII 字节码传输。
1.2 HTTP/1.0
HTTP/1.0 通过请求头和响应头实现了很多特性,如 多文件类型 的支持等。
发请求时通过 HTTP 请求头告诉服务器期待返回的文件类型、采取的压缩形式、提供的文件语言及编码,请求头格式如下:
accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh
服务器接收到浏览器请求后,会根据请求头信息准备响应数据(不一定都能支持),通过响应头中的字段告诉浏览器最终的响应数据格式(即处理方式),如:
content-encoding: br
content-type: text/html; charset=UTF-8
通过请求头和响应头实现的其他特性:
- 引入 状态码 通知浏览器服务器的处理状态
- 提供 Cache 缓存机制 减轻服务器的压力
- 请求头加入 用户代理 字段使服务器能够统计客户端基础信息
1.3 HTTP/1.1
在 1.0 基础上进行了多项改进:
- 改进持久连接
一个 TCP 连接上允许传输多个 HTTP 请求,有效减少 TCP 建立连接和断开连接的次数,减轻服务器额外压力。HTTP/1.1 中持久连接默认开启,手动关闭需要在 HTTP 请求头中加上 Connection: close
。目前浏览器对同一个域名默认允许同时建立 6 个 TCP 持久连接,因此可以使用 CDN 实现 域名分片 机制进行优化。
- 不成熟的 HTTP 管线化
管线化即将多个 HTTP 请求整批提交给服务器解决 队头阻塞 ( TCP 通道中未及时返回的请求阻塞后续所有请求) 问题的技术,但已被 FireFox、Chrome 放弃。
- 虚拟主机支持
请求头中增加 Host 字段表示当前域名地址,实现在一台物理主机上绑定多个拥有独立域名的虚拟主机,进行不同处理。
- 动态生成内容的支持
动态生成的页面在传输数据前不知道最终的 Content-Length
(数据大小),HTTP/1.1 引入 Chunk transfer 机制,服务器会将数据分割成若干任意大小的数据块,每个数据块发送时会附带上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。
- 客户端 Cookie、安全机制
2. HTTP/2
2015 年 5 月正式发布的 HTTP/2 协议能带来 20%~60% 的效率提升。
2.1 HTTP/1.1 缺陷
- TCP 的慢启动
慢启动是 TCP 减少网络拥塞的策略,慢启动使 TCP 连接建立完成后请求关键资源的耗时增加,带来性能问题。
- 多条 TCP 连接竞争带宽
带宽不足时各个 TCP 连接会动态减慢接收数据的速度,多条 TCP 连接无法区分关键资源(如 CSS、JavaScript 文件等)和普通资源(图片、视频等),可能影响关键资源的下载速度。
- 队头阻塞
持久连接公用一个 TCP 管道,数据不能并行请求,会阻塞一些数据的预处理(如提前做图片文件的编解码),很不利于浏览器的优化。
2.2 使用多路复用优化缺陷
2.2.1 缺陷解决
HTTP/2 中一个域名只使用一个 TCP 长连接传输数据,整个页面资源的下载只需要一次慢启动,也避免了多条 TCP 连接竞争带宽问题,而且并行请求解决了队头阻塞问题。
HTTP/2 使用了多路复用技术,将请求分成一帧一帧的数据去传输,当收到一个优先级高的请求(js 或 css 关键资源请求)时,服务器可以暂停之前的请求来优先处理关键资源的请求。
2.2.2 多路复用实现
HTTP 的多路复用技术是通过在协议栈中添加二进制分帧层来实现。
2.2.3 其他特性
- 可设置请求优先级
HTTP/2 在发送请求时可以标上优先级,服务器接收到请求后会优先处理高优先级请求。
- 服务器推送
HTTP/2 可以直接将数据提前推送到浏览器,例如当用户请求一个 HTML 页面之后,服务器附带将要使用的重要 css 和 js 文件一并发送给浏览器,加速页面加载。
- 头部压缩
提高传输效率,在没有请求体时尤为明显。
3. HTTP/3 & QUIC 协议
3.1 HTTP/2 缺陷
- TCP 队头堵塞
虽然 HTTP/2 解决了应用层队头阻塞问题,但 HTTP/2 依然基于为单连接而设计的 TCP 协议,在 TCP 传输过程中,由于单个数据包的丢失而造成的阻塞称为 TCP 上的队头阻塞。数据传输过程中,若有一个数据因为网络故障或其他原因而丢包,整个 TCP 的连接会处于暂停状态,需要等待丢失的数据包重传。
在 HTTP/2 中,多个请求跑在一个 TCP 管道中,任意一路数据流中出现丢包都会阻塞该 TCP 连接中的所有请求。由于 HTTP/1.1 浏览器为每个域名同时开启了 6 个 TCP 连接,根据测试数据表明,当系统丢包率达到 2% 时,HTTP/1.1 的传输效率反而比 HTTP/2 更好。
- TCP 建立连接延时较长
建立 TCP 连接时,三次握手需要 1.5 RTT,若使用 HTTPS (TLS 协议) 进行安全传输大致需要 1~2 RTT 建立连接。总之,在传输数据前需要花费 3~4 个 RTT。
RTT (Round Trip Time)
即网络往返延迟,指数据在客户端与服务器的一次往返时间(从发送数据开始,到发送端收到确认),RTT 是反映网络性能的一个重要指标,通常 1 个 HTTP 的数据包在 14KB 左右
- TCP 协议僵化
TCP 协议的升级很困难,中间设备(路由器、防火墙、NAT、交换机等)可能因不理解新协议数据包内容而直接丢弃数据包;TCP 协议通过操作系统内核来实现,通常操作系统的更新滞后于软件的更新。
3.2 QUIC 协议
由于 TCP 协议僵化,中间设备只认 TCP / UDP 协议,HTTP/3 基于 UDP 实现了类似 TCP 的多路数据流、传输可靠性等功能,称为 QUIC 协议。HTTP/3 则是基于 QUIC 协议,集成了 TCP + HTTP/2 多路复用 +TLS 等功能的一套协议。
- 实现了类似 TCP 的流量控制、传输可靠性功能
虽然 UDP 不提供可靠性传输,但 QUIC 在 UDP 基础上增加一层来保证数据可靠性传输,提供了数据包重传、拥塞控制等一些 TCP 中存在的特性。
- 集成 TLS 加密功能
目前 QUIC 使用 TLS1.3,相较于早期版本减少了握手花费的 RTT 个数。
- 实现了 HTTP/2 的多路复用功能
QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流, 解决了 TCP 的队头阻塞问题。
- 实现了快速握手功能
QUIC 基于 UDP,可以实现使用 0-RTT 或 1-RTT 建立连接,大大提升首次打开页面的速度。
3.3 HTTP/3 挑战
- 服务器和浏览器端对 HTTP/3 支持度低
- 系统内核对 UDP 的优化远不及 TCP,导致 HTTP/3 的部署存在很大问题
- 中间设备僵化,对 UDP 的优化程度远低于 TCP,据统计使用 QUIC 协议有 3%~7% 丢包率