近年来,http网络请求量日益添加,如下是httparchive统计,从2012-11-01到2016-09-01的请求数量和传输大小的趋势图:javascript
当前大部份客户端&服务端架构的应用程序,都是用http/1.1链接的,现代浏览器与单个域最大链接数,都在4-6个左右,由上图Total Requests数据,若是不用CDN分流,平均有20个左右的串行请求。
HTTP2 是1999年发布http1.1后的一次重大的改进,在协议层面改善了以上问题,减小资源占用,来,直接感觉一下差别:php
HTTP/2 is the future of the Web, and it is here!
这是 Akamai 公司创建的一个官方的演示,用以说明 HTTP/2 相比于以前的 HTTP/1.1 在性能上的大幅度提高。 同时请求 379 张图片,从Load time 的对比能够看出 HTTP/2 在速度上的优点。css
SPDY 系列协议由谷歌开发,于 2009 年公开。它的设计目标是下降 50% 的页面加载时间。当下不少著名的互联网公司都在本身的网站或 APP 中采用了 SPDY 系列协议(当前最新版本是 SPDY/3.1),由于它对性能的提高是显而易见的。主流的浏览器(谷歌、火狐、Opera)也都早已经支持 SPDY,它已经成为了工业标准,HTTP Working-Group 最终决定以 SPDY/2 为基础,开发 HTTP/2。HTTP/2标准于2015年5月以RFC 7540正式发表。java
可是,HTTP/2 跟 SPDY 仍有不一样的地方,主要是如下两点:node
HTTP/2 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
HTTP/2 消息头的压缩算法采用 HPACK ,而非 SPDY 采用的 DEFLATE(感谢网友 逸风之狐指正)git
协议文档请见:rfc7540:HTTP2github
HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式算法
由上图能够看到HTTP2在原来的应用层和HTTP层添加了一层二进制传输。chrome
二进制协议的一个好处是,能够定义额外的帧。
HTTP/2 定义了近十种帧(详情可分析抓包文件),为未来的高级应用打好了基础。若是使用文本实现这种功能,解析数据将会变得很是麻烦,二进制解析则方便得多。
RFC7540:Frame Definitions
协议中定义的帧
HTTP/2 复用TCP链接,在一个链接里,客户端和浏览器均可以同时发送多个请求或回应,并且不用按照顺序一一对应,这样就避免了"队头堵塞"(见TCP/IP详解卷一)。
每一个 Frame Header 都有一个 Stream ID 就是被用于实现该特性。每次请求/响应使用不一样的 Stream ID。就像同一个 TCP 连接上的数据包经过 IP: PORT 来区分出数据包去往哪里同样。
rfc7540: HTTP2 Multiplexing中对Multiplexing的说明
Streams and Multiplexing A "stream" is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection. Streams have several important characteristics: o A single HTTP/2 connection can contain multiple concurrently open streams, with either endpoint interleaving frames from multiple streams. o Streams can be established and used unilaterally or shared by either the client or server. o Streams can be closed by either endpoint. o The order in which frames are sent on a stream is significant. Recipients process frames in the order they are received. In particular, the order of HEADERS and DATA frames is semantically significant. o Streams are identified by an integer. Stream identifiers are assigned to streams by the endpoint initiating the stream.
数据流发送到一半的时候,客户端和服务器均可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的惟一方法,就是关闭TCP链接。这就是说,HTTP/2 能够取消某一次请求,同时保证TCP链接还打开着,能够被其余请求使用。
HTTP/2 对消息头采用 HPACK 进行压缩传输,可以节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了不少带宽资源。
HTTP2对http头创建索引表,相同的头只发送hash table 的index, 同时还用了霍夫曼编码和传统的gzip压缩。
服务端可以更快的把资源推送给客户端。例如服务端能够主动把 JS 和 CSS 文件推送给客户端,而不须要客户端解析 HTML 再发送这些请求。当客户端须要的时候,它已经在客户端了。
那么存在一个问题,若是客户端设置了缓存怎么办。有三种方式(来自社区)
cache-digest(提案)
HTTP2容许浏览器指定资源的优先级。
主流浏览器都只支持 HTTP/2 Over TLS
node中能够用spdy模块来启动应用,spdy的api,与https是一致的且主流浏览器只支持HTTP/2 Over TLS,须要配置 私钥和证书,本地自签名服务器配置可参考引用6,7。
const express = require('express'); const fs = require('fs'); const http2 = require('spdy'); const path = require('path'); const options = { key: fs.readFileSync('./keys/privatekey.pem'), cert: fs.readFileSync('./keys/certificate.pem') }; const app = new express(); http2 .createServer(options, app) .listen(8080, ()=>{ console.log(`Server is listening on https://localhost:8080. You can open the URL in the browser.`) } ) app.use("/",(req,res)=>{ res.send("hello http2!"); })
如上,对于已存在的项目只要修改几行代码就可使用http2.0了。
请求头和响应头:
说明:新版的Chrome,对不安全的证书(如本地的自签名服务)会降级到http1.1,firefox不会出现此问题。
启动server push
app.get("/",(req,res)=>{ var stream = res.push('/app.js', { //服务器推送 status: 200, // optional method: 'GET', // optional request: { accept: '*/*' }, response: { 'content-type': 'application/javascript' } }) stream.on('error', function() { }) stream.end('console.log("http2 push stream, by Lucien ");') res.send(`hello http2! <script src="/app.js"></script>`);//express 并无host static ,这个app.js 来自push })
响应
能够用chrome 内部自带的工具(chrome://net-internals/)查看http2流量,但这个包信息量比较少,结构不如咱们熟悉的Fiddler or Wireshark清晰。
Fiddler是直接做为中间代理,能够做为客户端直接与服务端通信,能够像浏览器那样直接解密https,直接看到https报文,
可是因为受限于.NET Framework暂不支持Http2.
用wireshark直接抓包 https:443端口的流量是这样的:
数据被加密了,协议细节彻底看不到。
这里介绍了一种方法获取私钥解包。
抓包https包时要把代理关了,否则私钥不是同一个,wireshark不能解包(被这个坑了两小时T T)。
一个包内有多个不一样的Steam ID
追踪解密后TCP流能够看到,因为多路复用,各个不一样的请求交替传输不一样的帧,因此流数据是乱的。但在同一帧内数据仍是正常的。
最后,HTTP2有更高的传输速度,更少的资源占用,能够去除各类性能优化tricks(如css sprite,inline-image.)
转向WEB开发的美好将来T.T