HTTP协议版本简介

status
category
date
summary
slug
icon
tags
password
HTTP协议规定了客户端和服务器之间通信的规范,在网络模型中位于应用层,它本身也是基于TCP和IP协议来发送请求和接受响应,默认HTTP使用80端口,HTTPS使用443端口。

HTTP的发展历史

HTTP的出现,主要是为了把HTML从服务器发送到客户端,但随着Web的发展,越来越多的需求推动着HTTP的发展:
  • HTTP/0.9:1991年发布,极其简单,只有一个get命令;
  • HTTP/1.0:1996年5月发布,增加了大量内容;
  • HTTP/1.1:1997年1月发布,进一步完善HTTP协议,是目前最流行的版本;
  • SPDY :2009年谷歌发布SPDY协议,主要解决HTTP/1.1效率不高的问题;
  • HTTP/2 :2015年借鉴SPDY的HTTP/2发布。

HTTP/0.9

HTTP/0.9是第一个HTTP协议,已经过时了。它只有GET方法,而且不支持协议头,因此只能传输纯文本,不能插入图片。 - 只有GET方法 - 服务器的返回内容只有HTML字符串 - 短连接
HTTP/0.9具有典型的无状态特性,每个事务单独处理,互不影响。HTTP的无状态性在0.9就已经形成了。一次HTTP请求首先要建立TCP连接,然后客户端发送数据,服务器返回数据,返回之后立即断开连接。即使请求的页面不存在,也不会返回任何错误码。

HTTP/1.0

HTTP/1.0相对于0.9来说是质的飞跃,它支持了在请求中指明HTTP版本,并且包含了一些我们如今非常熟悉的概念:首部、响应码、更多的请求方法……
  • 支持头部
  • 添加了响应码
  • 添加了POST、HEAD等请求方法
  • 返回内容不限于超文本
  • 短连接
1.0版本的HTTP最明显的缺点,与0.9相同,那就是短连接,这会造成两个问题,分别是影响HTTP通信的两个方面:速度与带宽。连接无法复用,导致每次请求都要进行TCP三次握手等流程,导致速度变慢;由此导致的带宽不足,会使后面的响应被阻塞。

HTTP/1.1

HTTP/1.1是第三个版本,也是目前使用最广泛的版本。它解决的1.0的绝大多数问题,接下来分别介绍一下:

长连接

HTTP/1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP/1.1默认支持长连接。
HTTP是基于TCP/IP协议的,创建一个 TCP 连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用长连接来依次发多个请求。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭 TCP 连接。
但长连接仅仅支持了连接在一定时间内不断开,仍然存在下列问题:
  • 串行的文件传输
  • 并行请求限制(6-8 个)造成的阻塞

管道机制

HTTP/1.1 中引入了管道机制(pipelining),即在同一个 TCP 连接中,客户端可以同时发送多个请求。这解决了上面提到的并行请求限制问题,因为管道机制支持一次性发送多个请求,但是仍然存在问题:服务器仍然按照请求顺序给与响应,因此如果前面的请求回应得很慢,后面就会有很多请求排队,这称为“队头阻塞(Head-of-line blocking)”。

节约带宽/断点续传

HTTP/1.1支持HEAD方法,只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。
这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。
HTTP/1.1还支持RANGE方法,只传送内容的一部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础。

HOST域

HTTP/1.0是没有host域的,HTTP/1.1才支持这个参数,并强制客户端添加。现在可以web server例如tomat,设置虚拟站点是非常常见的,也即是说,web server上的多个虚拟站点可以共享同一个ip和端口。

SPDY

2012年google如一声惊雷提出了SPDY的方案,优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体如下:
  1. 降低延迟,针对HTTP高延迟的问题,SPDY优雅的采取了多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了HOL blocking的问题,降低了延迟同时提高了带宽的利用率。
  1. 请求优先级(request prioritization)。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
  1. header压缩。前面提到HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。
  1. 基于HTTPS的加密协议传输,大大提高了传输数据的可靠性。
  1. 服务端推送(server push),采用了SPDY的网页,例如我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了。SPDY构成图:
    1. notion image
SPDY位于HTTP之下,TCP和SSL之上,这样可以轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可以使用已有的SSL功能。

HTTP/2.0

HTTP/2.0是HTTP协议自1999年HTTP/1.1发布后的首个更新,主要基于SPDY协议,于2015年2月17日被批准。主要特点:
  • HTTP/2采用二进制格式而非文本格式
  • HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
  • HTTP/2使用报头压缩,降低了开销
  • HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
  • HTTP/2相比HTTP/1.1的修改并不会破坏现有程序的工作,但是新的程序可以借由新特性得到更好的速度。
  • HTTP/2保留了HTTP/1.1的大部分语义,例如请求方法、状态码乃至URI和绝大多数HTTP头部字段一致。而 HTTP/2 采用了新的方法来编码、传输客户端——服务器间的数据。

和SPDY的主要区别

HTTP2.0可以说是SPDY的升级版(其实原本也是基于SPDY设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,如下:
  1. HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
  1. HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE

全新的二进制

HTTP/1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

多路复用

HTTP/2.0 使用了多路复用的技术,做到同一个 TCP 连接并发处理多个请求,而且并发请求的数量比 HTTP/1.1 大了好几个数量级。当然 HTTP1.1 也可以多建立几个 TCP 连接,来支持处理更多并发的请求,但是创建 TCP 连接本身也是有开销的。
HTTP/2 由于支持了二进制流,所以解决了队头阻塞的问题。通过分帧给每个帧打上流的 ID 去避免依次响应的问题,对方接收到帧之后根据 ID 拼接出流,这样就可以做到乱序响应从而避免请求时的队首阻塞问题。但是 TCP 层面的队首阻塞是 HTTP/2 无法解决的(HTTP 只是应用层协议,TCP 是传输层协议),TCP 的阻塞问题是因为传输阶段可能会丢包,一旦丢包就会等待重新发包,阻塞后续传输,这个问题虽然有滑动窗口(Sliding Window)这个方案,但是只能增强抗干扰,并没有彻底解决。
TCP 连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立好的连接,并且这个连接可以支持瞬时并发的请求。

数据压缩

来自Mozilla的Patrick McManus通过计算消息头对平均页面负载的印象,对此进行了形象且充分的说明:
假定一个页面有80个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1400字节的消息头(着同样也并不少见,因为Cookie和引用等东西的存在), 至少要7到8个来回去“在线”获得这些消息头。这还不包括响应时间——那只是从客户端那里获取到它们所花的时间而已。
这全都由于TCP的慢启动机制,它会基于对已知有多少个包,来确定还要来回去获取哪些包 – 这很明显的限制了最初的几个来回可以发送的数据包的数量.
相比之下,即使是头部轻微的压缩也可以是让那些请求只需一个来回就能搞定——有时候甚至一个包就可以了。这种开销是可以被节省下来的,特别是当你考虑移动客户端应用的时候,即使是良好条件下,一般也会看到几百毫秒的来回延迟。

服务器推送

网站为了使请求数减少,通常采用对页面上的图片、脚本进行极简化处理。但是,这一举措十分不方便,也不高效,依然需要诸多HTTP链接来加载页面和页面资源。
HTTP/2引入了服务器推送,即服务端向客户端发送比客户端请求更多的数据。这允许服务器直接提供浏览器渲染页面所需资源,而无须浏览器在收到、解析页面后再提起一轮请求,节约了加载时间。

HTTP/3.0

即将到来的 HTTP/3.0 将弃用 TCP 协议,改为基于 UDP 协议实现的 QUIC 协议。

在传输层解决队头阻塞

上面说到的 HTTP/2.0 虽然通过乱序响应解决了队首阻塞的问题,但只是解决了应用层的问题,传输层的 TCP 协议仍然要一帧一帧地传输二进制流数据,一旦某个流的数据丢包,则同样会阻塞它之后和它毫不相关的数据传输。而 QUIC 因为基于 UDP 协议,所以不同流的数据完全独立传输,重传时也互不干扰。

简化重复连接

客户端第一次连接服务器会发送 Hello Packet,服务器会返回一个数据包,这个数据包中包含了加密的 SYN cookie。因为连接过一次,客户端会保留服务器的安全证书,之后建立连接都会更方便,速度比每次建立 TCP 连接自然要快很多。即使有一些问题存在,但是解决问题的开销并不大。例如,客户端无法解密 SYN cookie或者证书过期,只需要请求服务器重新发送安全证书即可。
另外,因为使用了 UDP 协议,所以客户端在发送 Hello Packet 之后,没有等待回复就直接发送后面的数据包了。为了预防丢包问题,客户端会在一段时间之后重新发送 Hello Packet,保证减少丢包出现的延迟。

快速重启会话

QUIC 的另一个特性就是切换网络时保持连接。当前移动用户在 3G、4G、WiFi 之间切换比较频繁,基于 TCP 协议,用户切换网络之后 IP 地址将发生改变,所以之前的连接不能继续保持。而 QUIC 建立了与 TCP 不同的连接标识方法,使得用户在切换网络后,凭借唯一身份标识 UUID 就可以直接恢复与服务器的连接。
参考:HTTP1.0、HTTP1.1 和 HTTP2.0 的区别
Loading...

© 刘口子 2018-2025