乐趣区

关于后端:HTTP-演进史

HTTP 的倒退要追溯到万维网的创造,1989 年,过后在 CERN 工作的 Tim Berners-Lee 博士写了一份对于建设一个通过网络传输超文本零碎的报告。这个零碎起初被命名为 Mesh,在随后的 1990 年我的项目施行期间被更名为万维网(World Wide Web)。

万维网在现有的 TCP 和 IP 协定根底之上建设,由四个局部组成:

  • 一个用来示意超文本文档的文本格式,超文本标记语言(HTML)。
  • 一个用来替换超文本文档的简略协定,超文本传输协定(HTTP)。
  • 一个显示(以及编辑)超文本文档的客户端,即网络浏览器。第一个网络浏览器被称为 WorldWideWeb
  • 一个服务器用于提供可拜访的文档,即 httpd 的前身。

HTTP/0.9 1991 年

最后的 HTTP 协定并没有版本号,0.9 实际上是为了跟后续的 1.0 版本作辨别。总的来说 0.9 版本非常简陋,性能繁多。

特点:

  • 只反对 GET 申请,在其前面跟上指标资源的门路
  • 没有 HTTP 头部

有余:

  • 因为没有 HTTP 头部,所以除了文本类型无奈辨别和传输其余类型
  • 没有状态码和错误码,一旦呈现问题,只能返回一个固定的谬误页面

一个典型的申请:

GET /mypage.html

一个典型的响应:

<html>
  这是一个非常简单的 HTML 页面
</html>

HTTP/1.0 1996 年

在 0.9 根底上做了扩大,反对传输更多类型的内容。

特点:

  • 在申请中明确了版本号
  • 减少响应状态码
  • 减少 HTTP 头,使传输资源更加灵便,如:

    • Content-type:通过指定不同的 MIME type,表明资源的格局,如 text/html、text/css、image/png、application/javascript、application/octet-stream 等
    • Accept-Encoding / Content-Encoding:表明客户端反对的压缩类型和响应中应用的压缩类型

有余:

  • 每个 TCP 连贯只能发送一个申请,造成了连贯效率低下。后续在申请和响应头中减少了一个非标准的 Connection: keep-alive,告知单方申请能够复用同一条 TCP 连贯而不是每次申请响应后都敞开连贯。不过因为不是规范字段,不同实现的行为可能不统一,因而没有从根本上解决。

一个典型的文本类型的申请和响应

GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
一个蕴含图片的页面
  <IMG SRC="/myimage.gif">
</HTML>

典型的图片类型的申请和响应

GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(这里是图片内容)

HTTP/1.1 1997 年

HTTP/1.1 打消了大量歧义内容并引入了多项改良

特点:

  • 长久连贯复用成为默认,不须要申明 Connection: keep-alive,想要敞开能够在响应中减少 Connection: close 申明
  • pipelining 管道,能够一次性发送多个申请,防止了此前一次只能发送一个申请的状况,不过响应须要依照发送的程序来回复。
  • 减少几种 HTTP 办法
  • 减少分块传输的流模式,响应头携带 Transfer-Encoding:chunked 并在每一个分块减少 Content-Length 表明以后块长度,并在所有内容传输实现的最初追加一个 Content-Length:0 表明传输实现。
  • 减少 range、Content-Range 相干头,用来支继续传和分段申请。

有余:

  • 存在 Head of line blocking 队头阻塞问题,即同一个连贯中有一个申请阻塞了,后续所有申请都将被阻塞。

通过同一个连贯实现的申请响应:

GET /zh-CN/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/Simple_header

200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

(content)

GET /static/img/header-background.png HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/Simple_header

200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

(image content of 3077 bytes)

HTTP/2 2015 年

说到 HTTP/2 就不得不提 SPDY,SPDY 是 Google 开发的一个凋谢网络协议,旨在通过缩小提早来放慢网页加载速度。SPDY 在许多方面是 HTTP/2 的先驱,并间接影响了 HTTP/2 的设计和实现。

特点:

  • 兼容 HTTP/1.1
  • 全副应用二进制传输,传输效率更高
  • 引入了多路复用技术,联合 stream 流和 frame 帧的概念,解决了队头阻塞问题。

    • HTTP/1.1 并发申请数量针对每个域名都有限度,而 HTTP/2 能够应用一个连贯发送不同业务申请,每个申请通过 streamID 辨别,每个 stream 中能够传输多个 message,每个 message 由多个 frame 组成,frame 就是传输的最小单位。
    • 发送时不同申请通过同一个连贯并发发送,服务端接到后处理一个就能够返回一个,响应时依据惟一的 streamID 组装响应内容即可。如此防止了 HTTP/1.1 的队头阻塞问题。
  • 反对首部压缩,在同一个连贯的不同申请中大部分 header 都是反复的,HTTP/2 应用 HPACK 算法对 header 进行压缩。压缩波及到很多细节办法

    • 动态表将常见的首部字段都编了号,发送这么首部时,其 key 名间接发送对应的编号即可。
    • 动静表一开始是空的,将随着申请过程中呈现的一些不在动态表中的首部填充进去,取得新的编号。
    • 不管动态表还是动静表,其 value 如果是变动的,则应用哈夫曼编码压缩。
  • 反对服务器推送,申请一个网页的同时,还可能须要网页中依赖的动态资源,此时服务端就能够推送这些资源,毋庸期待客户端被动申请。

有余:

  • HTTP/2 作为应用层协定实际上曾经比拟完满了,但因为基于 TCP,所以防止不了受 TCP 的个性所影响导致的性能瓶颈,例如三次握手和四次挥手,慢启动和拥塞管制等等,严格来说这些不能算是问题,是设计理念不同的必然结果。
  • 要求 TLS 加密,也减少了建设连贯的耗时
  • 挪动设施可能频繁切换信号源,导致 socket 四元组发生变化,连贯被迫生效,须要重连。

首部压缩的例子:

动态表包含了一些罕用的首部字段名称和值。例如:

  • 索引 1::authority
  • 索引 2::method: GET
  • 索引 40:content-type: application/json

动静表最后是空的,但会随着连贯的应用而填充。假如咱们有一个申请,其中包含一个不常见的首部字段:

  • custom-header: example-value

这个字段能够增加到动静表中,并调配一个索引,例如索引 41。

咱们能够应用动态表和动静表中的索引来示意这些字段:

  • :method: GET 在动态表中,索引为 2
  • :authority: www.example.com 能够应用索引 1 和哈夫曼编码来压缩 www.example.com
  • custom-header: example-value 在动静表中,索引为 41

最终的首部压缩后果:

  • 索引 2
  • 索引 1 + 哈夫曼编码的 www.example.com
  • 索引 41 + 哈夫曼编码的 www.example.com

HTTP/3 2018 年提案 2020 年正式

HTTP/3 是基于 QUIC 协定的 HTTP 版本,致力于进一步提高性能。

特点:

  • 在 UDP 根底上构建,满足牢靠数据传输的同时,相较 TCP 有很大性能晋升。
  • 基于 TLS 1.3 疾速建设平安连贯
  • 连贯迁徙,不应用 TCP 四元组而是应用一个 64 位 ID 来标识连贯,当产生网络环境的变动时,能够不须要从新建设连贯。

不过 HTTP/3 的改变相对来说是最大的,目前看推广的覆盖率并没有之前的速度快。

参考:

HTTP 的倒退:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_H…

HTTP 协定演进与各版本个性:https://www.biaodianfu.com/http.html

本文由 mdnice 多平台公布

退出移动版