网络2️⃣HTTP-特性、版本

1、HTTP 特性

以 HTTP/1.1 为例

1.1、优点

  1. 简单
    • 报文格式 header + body,首部信息格式 key-value
    • 易于理解,降低了学习和使用门槛。
  2. 灵活和易于扩展
    1. HTTP 中的请求方法、URI/URL、状态码、首部字段,允许开发人员自定义和扩充
    2. HTTP 工作在应用层(OSI 第七层),其下层可以随意变化。
      • HTTPS:HTTP 与 TCP 层之间增加 SSL/TLS 安全传输层。
      • HTTP/1.1 和 2.0 使用 TCP,而 3.0 改用 UDP。
  3. 应用广泛和跨平台

无状态:HTTP 不保存通信状态,对于发送过的请求或响应都不做持久化处理。

每当有新的请求发出,都会有新的响应。

  1. 好处减少服务器 CPU 和内存消耗,将更多资源用于对外提供服务。
  2. 坏处难以完成关联性的操作
    • 假设用户登录->添加购物车->下单->支付,这一系列关联操作都需要知道用户身份。
    • 服务器不知道这些请求是有关联的,每次都要问一遍身份信息。
    • 解法方案有很多种,比较简单的方式是 Cookie 技术。

Cookie 技术:通过在请求和响应报文中写入 Cookie 信息,来控制客户端的状态。

交互过程如下

  • 客户端首次访问服务器,检查到本地无 Cookie,直接发起请求

  • 服务端生成 Cookie,在响应报文中添加 Set-Cookie 首部字段,返回响应。

  • 客户端

    • Cookie 信息保存在本地

    • 再次请求访问服务器时,在请求报文中带上 Cookie

      image-20220303180154142

1.3、不安全 - HTTPS 🔥

HTTP 信息不安全,具体体现为三方面。

  1. 无加密:采用明文传输。👉可能被窃听
  2. 无认证:不验证通信方的身份。👉可能遭遇伪装
  3. 无完整性保护:无法证明报文完整性。👉 可能被篡改

HTTPS 可以解决 HTTP 的三方面不安全,

也就是在 HTTP 和 TCP 之间引入 SSL/TLS 层。

1.4、性能 🔥

HTTP 基于 TCP/IP,采用请求-应答的通信模式。

由此决定了 HTTP 的性能。

1.4.1、长连接

  • 短连接(HTTP/1.0):

    • 客户端每发起一个 HTTP 请求,都新建一次 TCP 连接(三握)。
    • 服务端响应后,关闭 TCP 连接(四挥)。
    • 结果:客户端只能串行请求,且增加了双方的通信开销
  • 长连接(HTTP/1.1):aka. 持久连接

    • 只要任意一端没有明确提出断连,则保持 TCP 连接状态

    • 如果 HTTP 长连接超过一定时间没有任何数据交互,服务端也会主动断连

    • 结果:减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻服务端的负载

      短连接与长连接

1.4.2、管道网络传输

HTTP/1.1 采用长连接,使管道(pipeline)网络传输成为可能。

aka. 管线化(pipelining)

  • 串行:发出请求后,需要得到响应才能发起下一个请求。
  • 并行管线化):无需等待响应,可直接发送下一个请求。
    • 好处减少整体的响应时间
    • 问题
      • 服务器必须按照接收请求的顺序,发送对这些管道化请求的响应。
      • 如果服务端在处理某个请求时耗时较长,会阻塞后续请求的处理(i.e. 队头阻塞

HTTP/1.1 没有默认开启管线化,大部分浏览器也不支持。

HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞(HTTP 层面)。

2、优化 HTTP/1.1

优化思路

  1. 尽量避免发送 HTTP 请求。
  2. 减少请求 HTTP 次数。
  3. 减少服务器的 HTTP 响应的数据大小。

2.1、避免发送请求

策略缓存

对于一些具有重复性的 HTTP 请求(e.g. 每次请求得到的响应数据相同),

可以将这对请求-响应的数据缓存在本地,下次可直接读取本地数据,无需经过网络请求。

2.2、减少请求次数

减少 HTTP 请求次数,自然就提升了 HTTP 性能。

三种思路

  • 减少重定向请求次数
  • 合并请求
  • 延迟发送请求

① 减少重定向请求次数

重定向请求:客户端请求的资源不在原有 URL 上,服务器会响应 302Location

客户端需要再对 Location 的 URL 发起请求以获取资源。

  • 重定向请求越多,网络中的 HTTP 请求就更多,会降低网络性能。

  • 对策:由代理服务器完成重定向的工作

  • 当代理服务器知晓了重定向规则后,可以进一步减少消息传递次数。

② 合并请求

把多个访问小文件的请求合并成一个大的请求。

  1. 减少了重复发送的 HTTP 首部
  2. 减少 TCP 连接数量,避免 TCP 握手和慢启动耗费的时间。

合并方式:将资源合并

参考思路

  1. 精灵图:将网页中会使用的多个小图片,使用 CSS Image Sprites 技术合成一个大图片,再根据 CSS 切割还原。
  2. 打包工具:使用 webpack 等打包工具,将 js、css 等资源打包成一个大文件。
  3. base64 编码:将图片等二进制数据 base64 编码后,以 URL 形式嵌入到 HTML 文件。

存在问题

  • 当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整大资源文件。
  • 显然带来了额外的网络消耗。

③ 延迟发送请求

策略按需获取

  • 对于 HTML 中的多个 URL,只获取当前需要的资源,而不是一次性获取。
  • 从而减少第一时间的 HTTP 请求次数。

2.3、减少响应的数据大小

对策压缩

对服务器响应的资源进行压缩,从而减少响应的数据大小。

① 无损压缩

无损压缩:资源经过压缩后信息不被破坏,还能完全恢复原样。

适用于文本文件、程序可执行文件、程序源代码。

步骤

  • 针对代码语法规则进行压缩
    • 通常代码文件都有很多换行符或者空格,以提高可读性。
    • 机器执行时不需要这些空白符,可先将这部分符号去掉。
  • 无损压缩:需要对原始资源建立统计模型,通常用哈夫曼编码算法生成二进制比特序列。
    • 常出现的数据:较短的二进制比特序列
    • 不常出现的数据、:较长的二进制比特序列

交互流程

  • 客户端:在 HTTP 请求报文的首部中,使用 Accept-Encoding 告知自己支持的压缩算法

    Accept-Encoding: gzip, deflate, br
    
  • 服务器:从中选择一个支持的/合适的算法,使用该算法对相应资源进行压缩。

    Content-Encoding: gzip
    

② 有损压缩

无损压缩**:解压的数据会与原始数据不同,但是非常接近。

通常用于多媒体数据,如音频、视频、图片。

3、版本 🔥

HTTP/1.1

① 性能提升

相比 HTTP/1.0

  • 长连接:改善了 HTTP/1.0 短连接造成的性能开销。
  • 管道网络传输:减少整体的响应时间。

② 缺陷

  • 报文首部Header):
    • 未经压缩就发送。首部信息越多延迟越大,导致只能压缩 Body 的部分
    • 冗长。每次互相发送相同的首部造成的浪费较多。
  • 请求/响应
    • 没有请求优先级控制
    • 请求只能从客户端开始,服务器只能被动响应
    • 响应的队头阻塞

上文中讲述了 HTTP/1.1 的优化思路,但优化程度是有限的。

下面介绍 HTTP/2 和 HTTP/2。

HTTP/2

HTTP/2 基于 HTTPS,安全性有保障。

HTT/1 ~ HTTP/2

① 性能提升

头部压缩 - HPACK

如果同时发出多个请求,Header 相同或相似,HTTP/2 会消除重复部分。

HPACK 算法。

  • 在客户端和服务器同时维护一张 Header 信息表,保存所有字段并生成一个索引号。
  • 不发送字段,只发送索引号

二进制格式

HTTP/1.1 报文是纯文本格式,计算机需要将报文转换为二进制。

HTTP/2 全面采用二进制格式,计算机可以直接解析,提高数据传输效率

HeaderBody 都是二进制,统称为Frame)。

  • 头信息帧(Headers Frame)

  • 数据帧(Data Frame)

    HTTP/1 与 HTTP/2

并发传输 - Stream

  • HTTP/1.1 基于请求-响应模型。

    • 同一个连接中,HTTP 完成一个事务(请求-响应),才能处理下一个事务。
    • 如果等待响应的时间过长,客户端无法发送后续请求(队头阻塞)。
  • HTTP/2 引入 Stream 概念。

    • 多个 Stream 复用同一条 TCP 连接。

    • Stream 可以包含多个 Message(报文),Message 可以包含多个 Frame。

    • 使用唯一的 Stream ID 区分 HTTP 请求,则通信双发可以并行交错地发送 Message。

服务器推送

服务端不再是被动地响应,可以主动向客户端发送消息

  • 和客户端一样,服务器可以建立 Stream
  • Stream ID 要求:客户端建立的 Stream 是奇数号,服务器建立的 Stream 是偶数号。

服务器推送的好处:可以减少消息传递次数

示例:客户端请求页面。

  • HTTP/1.1:客户端从服务器获取 HTML 文件后,可能需要请求 CSS 等文件。
  • HTTP/2:客户端从服务器获取 HTML 文件后,服务器可以直接主动推送 CSS 等文件。

img

② 缺陷

HTTP/2 通过 Stream 解决了 HTTP/1 队头阻塞

但存在另一个问题, TCP 层面的队头阻塞(aka. HTTP/2 队头阻塞)。

原因:HTTP/2 基于 TCP 传输数据,而 TCP 是面向字节流的协议。

  • TCP 收到字节数据时会保存到内核缓冲区。
  • 如果当前接收到的数据是完整且连续的,Kernel 才会将这部分返回给 HTTP 应用。
  • 如果某一个字节数据没有收到,后续接收的数据只能放在内核缓冲区,直到该字节数据到达时才能从 Kernel 中拿到数据

示例

  • 发送方:发送 packet 1-6,其中 packet 3 在网络中丢失了。

  • 接收方

    • Kernel 接收到 packet 1-2,由于是连续的,返回给应用层。

    • Kernel 接收到 packet 4-6,由于中间缺了 packet3,无法返回给应用层。

      img

结果:触发 TCP 重传机制。

  • 只有等到 packet 3 重传成功后,接收方的应用层才可以从内核中读取到数据。
  • i.e. 一个 TCP 连接中的所有的 HTTP 请求,必须等待丢失包的重传

HTTP/3

① 队头阻塞

HTTP/1.1HTTP/2 都存在队头阻塞问题。

  • HTTP/1.1管道网络传输解决了请求的队头阻塞,没有解决响应的队头阻塞(HTTP 层面)

  • HTTP/2Stream 解决了 HTTP 队头阻塞 ,没有解决 TCP 丢包带来的阻塞(TCP 层面)

HTTP/2 队头阻塞,是因为采用了 TCP 作为传输层协议,

因此,HTTP/3 改用 UDP 传输层协议

  • UDP 是面向无连接的(不保序,不重传),不会导致 HTTP/2 队头阻塞。

  • 基于 UDP 的 QUIC 协议,可以实现类似 TCP 的可靠传输

    HTTP/1 ~ HTTP/3

② QUIC

快速 UDP 互联网连接(Quick Udp Internet Connection)

无队头阻塞

  • QUIC 具有类似 HTTP/2 Stream多路复用的概念。

    • QUIC 可以在同一条连接上并发传输多个 Stream。
    • Stream 可以理解为一条 HTTP 请求。
  • QUIC 具有保证传输可靠性的机制,避免队头阻塞。

    • HTTP/2:只要发生丢包,所有 Stream 都会阻塞。
    • QUICStream 之间互相独立,发生丢包时只阻塞丢包的 Stream,不影响其它 Stream(避免了队头阻塞问题)。

更快的连接建立

  • HTTP/1.x 和 HTTP/2

    • TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层。
    • 需要分批次握手(先 TCP 握手,再 TLS 握手),耗时多个 RTT。
  • HTTP/3

    • QUIC 内部包含 TLS(1.3),它在自己的帧会携带 TLS 里的“记录”。

    • 在传输数据前进行 QUIC 协议握手,只需 1RTT 即可完成建立连接与密钥协商

      TCP HTTPS(TLS/1.3) 和 QUIC HTTPS

首次连接 & 恢复连接

  • 首次连接(1RTT):QUIC 握手信息(连接信息 + TLS 信息)

  • 恢复会话(0RTT):应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送。

连接迁移

  • HTTP 1.x 和 HTTP 2
    • 基于 TCP,通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。
    • 如果 IP 地址变化就需要重新连接(e.g. 从 WiFi 切换到移动数据),TCP 三握+TLS 四握会给用户带来体验上的卡顿。
  • HTTP 3
    • 基于 QUIC,通过连接 ID 来标记通信的两个端点。
    • 即使 IP 地址变化,只要仍保存上下文信息(连接 ID、TLS 密钥等),就可以复用连接。

总结:QUIC 是一个基于 UDP 的,伪 TCP + TLS + HTTP/2多路复用的协议。

现状:QUIC 是新协议,很多网络设备不兼容,会当作 UDP 处理,甚至可能会被直接丢包。

posted @ 2022-02-28 14:56  Jaywee  阅读(126)  评论(0编辑  收藏  举报

👇