贯穿 HTTP 的发展史

1,521 阅读10分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

HTTP(超文本传输协议)是一个用于传输超媒体文档(如 HTML)的应用层协议。

特点

  • 灵活可扩展:能传输文本、图片及视频等数据。
  • 可靠传输:基于 TCP/IP 的协议,也继承了 TCP/IP 可靠的特点。
  • 请求应答模式:一方发出消息,另外一方响应。
  • 无状态:每次的请求和响应都是独立的。
  • 不安全:明文传输、无完整性验证、无身份验证

目前 HTTP/3 仍然是草案状态,但最新的 Chrome 浏览器已经默认支持它。Chrome在浏览器市场占据70%的市场份额,所以可以说 HTTP/3 已经进入主流。HTTP/3 的出现旨在让 Web 更加高效、安全并缩短内容交付延迟,是 HTTP2 的完善。其弃用TCP协议,改为使用基于UDP的QUIC协议实现。

那 QUIC 相较于 TCP 的优点是什么?为了更好地理解TCP的不足,从头开始梳理是最好的办法。

HTTP 0.9

1991年,万维网协会(W3C)和互联网工程任务组(IETF)制定 HTTP 0.9标准。因这个年代互联网还在普及,只支持了 GET 请求,且不支持请求头。由于没有协议头,造成HTTP/0.9只支持传输纯文本和HTML文件(不能插入图片、视频等其他格式)。

因HTTP本身的无状态性,每个事务独立进行处理,事务结束就释放连接。传输过程首先需要建立客户端与服务端的TCP连接,然后客户端发起请求,服务端返回页面内容,然后连接会关闭。如果请求页面不存在,也不会返回任何错误的状态码。

HTTP 1.0

特性

1996年,HTTP/1.0 版本发布,相较于HTTP/0.9新增了如下主要特性。

  1. 请求方式多样化:增加 POST、HEAD。(POST允许客户端向服务端提交数据)
  2. 增加HTTP头的概念:无论对请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性。在HTTP头的帮助下,具备除传输文本HTML以外其他类型文档的能力,这得益于Content-Type
  3. 增加状态码:使客户端了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)。
  4. 增加缓存机制。
  5. 增加身份认证。

缺陷

HTTP/1.0还是存在缺陷。

  1. 短连接:TCP连接无法复用,即每次请求都需要与服务器建立TCP连接,完成请求处理后立刻断开连接。
  2. 带宽浪费:客户端无法请求某个对象的一部分。
  3. 队头阻塞:即当页面需请求多资源时,队头阻塞会导致请求达到阈值时,剩余资源需等待先前资源完成后才可发起请求,带宽无法被充分利用。

HTTP 1.1

特性

1997年,HTTP/1.1发版,进一步完善HTTP协议,具体优化点如下。

  1. 增加缓存处理机制 HTTP/1.0依赖于 Expires 字段作为强缓存判断的标准,HTTP/1.1 新增 Cache-Control字段,优先级高于 Expires。
    若未命中强缓存,则判断是否命中协商缓存。HTTP/1.0中,服务端/客户端通过 Last-Modified/If-Modified-Since字段判断。HTTP/1.1中,新增 Etag/If-None-Match判断。

  2. 长连接 HTTP/1.1默认开启长连接(Connection:keep-alive),可在一个TCP连接上传送多个 HTTP 请求和响应,减少建立、关闭连接的消耗和延迟。keep-alive 是有时间限制的,这个时间可通过设置 HTTP 进程的配置文件来修改,这个时间很短,超出时间后,又需要重新建立连接,所以还是无状态的。

  3. 带宽优化 HTTP/1.0中存在浪费带宽现象,例如客户端只需某个对象一部分,而服务端却把整个对象传送过来;HTTP/1.1中请求头增加 range 字段,允许请求资源的某一个部分(返回状态码:206),断点续传的基础。

  4. HOST头 HTTP/1.0中,每台服务器绑定一个唯一IP地址。因此,请求URL不包含主机名。但随着虚拟主机技术发展,一台服务器可以存在多个虚拟主机,并且它们共享同一个IP。所以 HTTP/1.1的请求信息和响应信息都应支持HOST头域。

  5. 增加错误状态码 新增24个状态码,如409表示请求资源与资源当前状态发生冲突;410表示服务器上某个资源被永久性删除。

  6. 增加管道化技术 允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。

缺陷

随着网络的发展,HTTP1.1还是暴露了一些局限性:

  1. 长连接使TCP连接可复用,但域名分片的情况下仍然需要建立多个 TCP 连接,给服务端造成压力。
  2. 管道化技术(pipelining)只解决了部分队头阻塞问题。虽客户端一次性可发出多个请求,但管道要求返回是按序的,那么前一个请求耗时过长,同样阻塞了后续请求内容的返回。
  3. HTTP/1.1 头部携带信息过头,在一定程度上增加了传输的成本。

HTTP 2.0

特性

2015年,HTTP/2.0发版,其使用基于TCP协议的SPDY协议,相较于HTTP/1.1新增了如下主要特性:

  1. 多路复用 HTTP/1.1是基于文本分割协议,所有的数据都是按顺序传输,不能并行传输。HTTP/2.0是基于二进制帧的协议,其中的帧标识数据,达到并行传输后,不会出现合并数据错乱的情况。

  2. 头部压缩 HTTP/1.1中头部元数据都是以纯文本的形式发送,会给请求增加500~8000字节的传输成本。HTTP/2.0通过静态字典表预定义61个header中的字段,如常规的:method GET:method POST等。通过动态字典表(队列)存储预定义之外的字段,添加位置从62开始,之后的传输时使用对应的索引即可。同时支持对String类型的Key-Value进行静态霍夫曼编码,减少传输体积的同时增加了安全性。

  3. 服务器推送 除最初请求的响应外,服务器还可以额外向浏览器端推送资源,无需浏览器端再次请求。HTTP/2.0出现不能代替WebSocket,因其无法将数据传输到客户端APP本身。

HTTP 3.0

HTTP/2.0 相较于HTTP1.1 虽大幅提升了性能,但由于其基于TCP协议,所以TCP的局限性是无法避免的。

TCP局限性

  1. 队头阻塞 HTTP/2.0多个请求在一个TCP连接中的,当TCP丢包,整个TCP都得等待重传,从而阻塞该TCP连接中的所有请求。TCP是字节流协议,TCP层必须保证收到字节数据是完整有序地,若序列号低的字段丢失,即使高的TCP字段被接收,应用层也无法从内核中读取这部分数据。

  2. TCP与TLS握手延迟 发起HTTP请求,需经过TCP三次握手和TLS四次握手,共需3个往返时延(Round-Trip Time)延迟。TCP 还具有拥塞控制的特性,所以建立连接 TCP 会有个慢启动的过程,会对 TCP 连接产生减速效果。

  3. 网络迁移需重新连接 TCP 连接由四元组(源IP、源端口、目标IP、目标端口)确定,若IP地址或端口变动,就会导致TCP与TLS重新握手,不利于移动设备切换网络。

QUIC的特性

文章开头已经说明 HTTP/3.0 是使用基于UDP协议的QUIC协议,其具备如下四个优势。

  1. 连接迁移 QUIC协议通过连接ID来标记两个端点。因此,即使移动设备网络变化,导致IP变化,只要仍保有(连接ID、TLS密钥),就可以"无缝"地复用原连接,消除重连的成本。

  2. 无队头阻塞 QUIC协议 与 HTTP/2 一样可并发传输多个 Stream。虽UDP不关系数据包丢失,但QUIC为了保证数据包可靠性,每个数据包都有一个序号唯一标识。当流中一个数据包丢失,即便流的其他数据包到达,数据也无法被HTTP/3.0读取,直到QUIC重传丢失的报文,数据才会交给 HTTP/3.0。QUIC连接上多个 Stream 之间没有依赖,都是独立的,某个流发生丢包,只会影响该流,其他流不受影响。

  3. 自定义拥塞控制 在TCP拥塞算法的基础上做的改进,如可插拔,应用程序层面就能实现不同的拥塞控制算法,不需操作系统和内核支持;单个应用程序的不同连接也能支持配置不同的拥塞控制;无需停机和升级就可实现拥塞控制的变更。单调递增的Packet Number,使QUIC能区分原始包和重传包,避免重传模糊问题。有更多的ACK块,支持256个ACK块。可精确计算RTT时间。

  4. 前向安全和前向纠错 发送一组数据之后,就对这组数据进行异或运算(效率高),并将结果也发送出去,那么接收方就有两份数据版本,可以对初始数据进行纠错和校验。以此保证了可靠性。

知识点

GET 和 POST的区别?

  1. GET请求数据显示在URL后,POST则在HTTP包体中。
  2. GET请求参数有限制(浏览器及服务器),POST请求没有限制。
  3. POST安全性比GET安全性高。

TCP 和 UDP 区别?

  1. TCP面向连接;UDP无连接。
  2. TCP基于字节流;UDP基于数据报文。
  3. TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
  4. TCP连接是点到点;UDP支持一对一、一对多、多对一和多对多的交互通信。
  5. TCP首部开销20字节;UDP只有8个字节。

常见状态码

2XX 表示请求成功响应。

  • 200 表示服务器请求成功响应。
  • 204 表示服务器请求成功响应,但没有资源可以返回,只在消息头返回发生变更的元信息。

3xx 表示要完成请求,需要进一步操作,通常,这些状态码用来重定向。

  • 301 表示永久重定向
  • 302 表示暂时重定向
  • 304 表示使用本地资源缓存。

4xx 表示浏览器端发生了一些错误。

  • 400 表示服务器不理解请求语法,一般是传参问题。
  • 401 表示需身份验证
  • 403 表示服务器拒绝请求。
  • 404 表示服务器找不到请求的网页,一般是地址错误。
  • 410 表示请求资源已永久删除。

5xx 表示服务器在处理请求时发生内部错误。

  • 500 表示服务器遇到错误,无法完成请求。
  • 501 表示服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能返回此代码。
  • 503 表示服务器目前无法使用(超载或停机维护)。
  • 504 表示服务器作为网关或代理,但是没有及时从上游服务器收到请求,请求过期前未响应。
  • 505 表示请求的 HTTP 版本不受支持。

参考

HTTP/3 强势来袭!
从HTTP到HTTP/3的发展简史
HTTP/3
HTTP 0.9 HTTP 1.0 HTTP 1.1 HTTP 2.0区别
HTTP的发展