链接没法复用会致使每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。node
head of line blocking会致使带宽没法被充分利用,以及后续健康请求被阻塞。git
HTTP1.0 -> HTTP1.1github
不过pipelining并非救世主,它也存在很多缺陷:npm
pipelining只能适用于http1.1,通常来讲,支持http1.1的server都要求支持pipelining浏览器
只有幂等的请求(GET,HEAD)能使用pipelining,非幂等请求好比POST不能使用,由于请求之间可能会存在前后依赖关系。服务器
head of line blocking并无彻底获得解决,server的response仍是要求依次返回,遵循FIFO(first in first out)原则。也就是说若是请求1的response没有回来,2,3,4,5的response也不会被送回来。网络
绝大部分的http代理服务器不支持pipelining。tcp
和不支持pipelining的老服务器协商有问题。性能
可能会致使新的Front of queue blocking问题。测试
多路复用经过多个请求stream共享一个tcp链接的方式,解决了http1.x holb(head of line blocking)的问题,下降了延迟同时提升了带宽的利用率。
HTTP/2.0规定了在客户端和服务器端会使用而且维护「首部表」来跟踪和存储以前发送的键值对,对于相同的头部,没必要再经过请求发送,只需发送一次。
事实上,若是请求中不包含首部(例如对同一资源的轮询请求),那么首部开销就是零字节。此时全部首部都自动使用以前请求发送的首部。
若是首部发生变化了,那么只须要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP2.0的链接存续期内始终存在,由客户端和服务器共同渐进地更新。
在应用层与传输层之间增长一个二进制分帧层,以此达到“在不改动HTTP的语义,HTTP 方法、状态码、URI及首部字段的状况下,突破HTTP1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。”
在二进制分帧层上,HTTP2.0会将全部传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中HTTP1.x的首部信息会被封装到Headers帧,而咱们的request body则封装到Data帧里面。
客户端和服务器能够把HTTP消息分解为互不依赖的帧,而后乱序发送,最后再在另外一端把它们从新组合起来。注意,同一连接上有多个不一样方向的数据流在传输。客户端能够一边乱序发送stream,也能够一边接收者服务器的响应,而服务器那端同理。
多路复用致使全部资源都是并行发送,那么就须要「优先级」的概念了,这样就能够对重要的文件进行先传输,加速页面的渲染。
服务器推送是指在客户端请求以前发送数据的机制。
另外有一点值得注意的是,客户端若是退出某个业务场景,出于流量或者其它因素须要取消server push,也能够经过发送RST_STREAM类型的frame来作到。
这里使用 Node.js 做为服务器端语言。
若是想要在生产环境中使用HTTP2,那么你能够去这里生成一个证书。
若是你仅仅开发环境使用,那么咱们能够本身生成一个自签名的TSL证书。
安装OpenSSH
使用OpenSSH生成私钥
openssl genrsa -des3 -passout pass:1234 -out server.pass.key 2048`
这里 1234
为私钥密码,若是你不想使用密码,则能够去除私钥密码,敲入以下密令:
openssl rsa -passin pass:x -in server.pass.key -out server.key
建立 证书签名请求
这里使用无密码私钥,若是使用带密码私钥,只需将server.key
更换为server.pass.key
便可,密令以下
openssl req -new -key server.key -out server.csr
建立证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
经过以上四个步骤,咱们获得了三个文件
server.key 你的TSL证书私钥
server.csr 你的TSL证书签名请求
server.crt 你的TSL证书
安装 node-http2 模块
npm install http2
建立服务器
var options = { key: fs.readFileSync('./server.key'), cert: fs.readFileSync('./server.crt') }; require('http2').createServer(options, function(request, response) { response.end('Hello world!'); }).listen(8080);
启动服务器
node index.js
使用浏览器访问
http://localhost:8080
到此,一个简单的Demo就完成了。
点击这里访问完整Demo
https://github.com/zhanyouwei...
经过上面两张截图能够发现,使用了HTTP2后,一样的请求,在数据传输大小与速度上都有很是大的提高,几乎能够预见,不久的未来,HTTP2将会大放异彩。