HTTP/1.0、HTTP/1.1、HTTP/2、HTTPS
1. HTTP发展历史
HTTP(超文本传输协议,HyperText Transfer Protocol)是建立在TCP协议之上的一种应用层网络协议。默认使用80端口,建立之初目的是为了将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。WEB2.0以后,页面变得越来越复杂,以及ajax的出现提供了一种向服务端获取数据的新方式,这些推动着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发布。
2. HTTP的优化
HTTP协议建立在TCP协议之上,所以HTTP协议的瓶颈及其优化技巧都是基于TCP协议本身的特性,比如TCP的三次握手和四次挥手以及每次建立连接带来的RTT延迟时间。
影响一个HTTP网络请求的因素主要有两个:带宽和延迟:
-
带宽:网络带宽是指单位时间内传输的数据量,是数据的传输能力。现在网络基础建设较为完善,基本不用担心带宽影响网速,所以目前影响HTTP网络请求性能的就是延迟了。
-
延迟:
1. 浏览器阻塞(head of line blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 6个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。这也是为何一些站点会有多个静态资源 CDN 域名的原因之一。
2. DNS查询(DNS Lookup):将域名解析为IP就是DNS查询,一般使用DNS缓存来减少这个时间。
3. 建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能携带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。
3. HTTP/1.1 和 HTTP/1.0 的区别
1. 缓存处理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since
来作为缓存判断的标准;HTTP/1.1 引入了更多的缓存控制策略:Cache-Control
、Etag/If-None-Match
等。
2. 错误状态管理:HTTP/1.1新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
3. 范围请求:HTTP/1.1在请求头引入了range
头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接,支持断点续传。
4. Host头:HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。
5. 持久连接:HTTP/1.1 最大的变化就是引入了持久连接(persistent connection),在HTTP/1.1中默认开启 Connection: keep-alive
,即TCP连接默认不关闭,可以被多个请求复用。
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close
,明确要求服务器关闭TCP连接。
6. 管道机制:HTTP/1.1中引入了管道机制(pipelining),即在同一个TCP连接中,客户端可以同时发送多个请求。
4. HTTP/1.1的缺点
HTTP/1.1 的持久连接和管道机制允许复用TCP连接,在一个TCP连接中,也可以同时发送多个请求,但是所有的数据通信都是按次序完成的,服务器只有处理完一个回应,才会处理下一个回应。比如客户端需要A、B两个资源,管道机制允许浏览器同时发出A请求和B请求,但服务器还是按照顺序,先回应A请求,完成后再回应B请求,这样如果前面的回应特别慢,后面就会有很多请求排队等着,这称为“队头阻塞(Head-of-line blocking)”
5. HTTP/2
HTTP/2以Google发布的SPDY协议为基础,于2015年发布。它不叫HTTP/2.0,因为标准委员会不打算再发布子版本了,下一个新版本将是HTTP/3。HTTP/2协议只在HTTPS环境下才有效,升级到HTTP/2,必须先启用HTTPS。HTTP/2解决了HTTP/1.1的性能问题,主要特点如下:
1. 二进制分帧:HTTP/1.1的头信息是文本(ASCII编码),数据体可以是文本,也可以是二进制;HTTP/2 头信息和数据体都是二进制,统称为“帧”:头信息帧和数据帧;
2. 多路复用(双工通信):通过单一的 HTTP/2 连接发起多重的请求-响应消息,即在一个连接里,客户端和浏览器都可以同时发送多个请求和响应,而不用按照顺序一一对应,这样避免了“队头堵塞”。HTTP/2 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息。并行地在同一个 TCP 连接上双向交换消息。
3. 数据流:因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM
帧),取消这个数据流。HTTP/1.1取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
4. 首部压缩:HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息压缩后再发送(SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法)。;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
5. 服务端推送:HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。
6. HTTPS
HTTPS可以说是安全版的HTTP,HTTPS基于安全SSL/TLS(安全套接层Secure Sockets Layer/安全传输层Transport Layer Security)层,即在传统的HTTP和TCP之间加了一层用于加密解密的SSL/TLS层。HTTP默认使用80端口,HTTPS默认使用443端口。
不使用SSL/TLS的HTTP通信,所有信息明文传播,会带来三大风险:
-
窃听风险:第三方可以获取通信内容;
-
篡改风险:第三方可以修改通信内容;
-
冒充风险:第三方可以冒充他人进行通信。
SSL/TLS协议是为了解决这三大风险而设计的,以期达到:
-
信息加密传输:第三方无法窃听;
-
校验机制:一旦被篡改,通信双方会立刻发现;
-
身份证书:防止身份被冒充。
6.1 SSL/TLS发展
-
SSL/1.0:1994年NetScape公司设计,未发布;
-
SSL/2.0:1995年NetScape公司发布,但存在严重漏洞;
-
SSL/3.0:1996年NetScape公司发布,得到大规模应用;
-
TLS/1.0:1999年互联网标准化组织(ISOC)接替NetScape公司,发布SSL的升级版TLS/1.0;
-
TLS/1.1:2006年发布;
-
TLS/1.2:2008年发布;
-
TLS/1.2修订版:2011年发布。
目前,应用最广泛的是 TLS/1.0 和 SSL/3.0,且主流浏览器已实现 TLS/1.2的支持。
6.2 SSL/TLS运行机制
SSL/TLS的基本思路是公钥加密法:客户端先向服务器索要并验证公钥,然后用公钥加密传输来协商生成“对话秘钥”(非对称加密),双方采用“对话秘钥”进行加密通信(对称加密)。
通信过程如下:
1. 客户端发出请求:给出支持的协议版本、支持的加密方法(如RSA公钥加密)以及一个客户端生成的随机数(Client random);
2. 服务端回应:确认双方通信的协议版本、加密方法,并给出服务器证书以及一个服务器生成的随机数(Server random);
3. 客户端回应:客户端确认证书有效,取出证书中的公钥,然后生成一个新的随机数(Premaster secret),使用公钥加密这个随机数,发送给服务端;
4. 服务端回应:服务端使用自己的私钥解密客户端发来的随机数(Premaster secret),客户端和服务端根据约定的加密方法,使用三个随机数,生成“对话秘钥”;
5. 会话通信:客户端和服务端使用“对话秘钥”加密通信,这个过程完全使用普通的HTTP协议,只不过用“会话秘钥”加密内容。
前四步称为握手阶段,用于客户端和服务端建立连接和交换参数。整个通信过程可用下图所示:
https.png6.3 HTTPS特点
-
缓存:只要在HTTP头中使用特定命令,就可以缓存HTTPS;
-
延迟:HTTP耗时 = TCP握手;HTTPS耗时 = TCP握手 + SSL握手。SSL握手耗时大概是TCP握手耗时的三倍左右。