HTTP/2概述
HTTP/2是下一代HTTP协议,主要基于Google的SPDY协议发展而来。目前由组织IETF HTTPbis Working Group进行设计。计划在2015年2月将HTTP/2送IETF成为RFC,在本文发布时HTP/2最新草稿版本为draft-16。
HTTP/2修改了传输方式以减小延时,让网页载入更快。同时在语义上最大程度的兼容HTTP/1.X,包括HTTP方法(GET,POST等),状态码,头信息等。
目前浏览器的支持情况
服务端支持情况
- Apache mod_spdy
- Nginx (不支持server push)
- Jetty Web Server
- node-spdy
- ……
厂商支持情况
- Wordpress.com
- LINE
- Amazon Kindle Fire
- Akamai
- Cloudflare
- ……
性能改善情况
google选取了TOP 25网站进行测试,结果显示基于明文TCP的SPDY页面载入时间减少了27%~60%,基于SSL的SPDY页面载入时间减少了39%~55%。
HTTP/2的特点
1.基于TLS(可选的):
HTTP/2可以基于明文的TCP连接,或者基于TLS连接。使用两种连接的进行协议协商的方法是不同的。
HTTP/2仍然沿用"http://","https://"的前缀,仍然沿用80,443端口。这样可以尽量减少对现有的网络设施(代理,防火墙等)进行改动,减小HTTP/2 推广的阻力。另一方面,意味着服务端和客户端需要一种方法来协商协议版本。
如果使"http://",即使用明文TCP,那么浏览器和服务端直接通过HTTP消息来协商使用的版本。如:支持HTTP/2的客户端在请求头中带上Upgrade: h2c
, Connection: Upgrade, HTTP2-Settings
。如果服务端也支持HTTP/2那么他们可以协商升级成HTTP/2协议。如果服务端对不支持,直接忽略这些头信息,依然按照HTTP/1.1协议进行处理。
如果使用"https://",即使用TLS连接,由于历史原因,有两种协议协商方法:NPN,ALPN。NPN全称是Next Protocol Negotiation, ALPN全称Application-Layer Protocol Negotiation。两种协商方法十分类似,在细节上有稍许不同,但是目标一致。在早些时候SPDY主要使用NPN,后来TLS工作小组考察了两种设计,最终选择ALPN作为RFC中的标准。简单的说,未来标准的协商方法是ALPN,不过一些已经实现了SPDY协议的软件为了向下兼容可能会依然兼容NPN。
2.使用二进制而不是文本
在HTTP/2中,直接使用二进制传输,基本的协议单位是帧(frame),且有固定长度的头以方便解析和多路传输。每个帧都有不同的类型和用途。例如,报头(HEADERS)和数据(DATA)帧组成了基本的HTTP请求和响应;其他帧,例如设置(SETTINGS)和推送承诺(PUSH_PROMISE)则用来实现HTTP/2的其他功能。
其中帧头包括以下信息:
- Length:payload的长度(不包括固定长度9字节的头)
- Type: frame的类型,不同类型消息体(payload)格式和内容不同
- Flags: 针对不同Type有不同的语义
- R: 预留,暂时没用
- Stream Identifier:stream的标识符
- Payload:具体Type不同,对payload格式的定义不同。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-+-----------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
3.仅一个TCP长连接,支持优先级的多路传输
这句话包括三个关键点:
-
一个TCP长连接:由于TCP建立连接慢的特点,每个请求都重新建立新的TCP连接是十分浪费的,所以HTTP/1.1中有了keepalive参数。虽然有了keepalive,但是有会Head-of-line blocking问题,即第一个响应慢了,会影响到后面所有的响应。于是HTTP/2支持在这个TCP连接中进行多路传输。
-
多路传输:HTTP/2中“请求-响应”称为一个stream,一个完整的stream由若干个frame组成,因此frame可以交错地传输。每个frame中带有一个streamId以标记属于哪个stream,奇数的id表示从客户端发的,偶数的id表示从服务端发的。
- 优先级:Stream是可以标记优先级的,这样可以要求服务器优先传回重要的资源,让页面渲染更快。实现原理很简单,因为stream由frame组成,一旦服务端收到高优先级的请求,它将暂停原先的发送原来的frame,而优先发送高优先级的stream的frame,通过这种方法来实现stream的优先级。
4.header压缩
由于HTTP的headers高度重复并且体积不小,很正常的希望通过对header的压缩来减小HTTP消息的体积,加速在网络上的传输,减少延时。 在SPDY中,使用DEFLATE方法来压缩headers,压缩效果不错,但是发现有安全隐患(CRIME attack),于是HTTPbis开始研究新的压缩方法,并称之为HPACK。
5.Server push
并不是为了替代轮询,而是类似HTTP/1中的Data URI scheme,将所需要的资源(图片,css,javascript)等和html整合在一起,放到一个响应中一次性取回。
具体的,服务器收到请求后,知道哪些资源(图片,css,javascript)客户端肯定会用到,于是主动的将这些资源push给客户端,由于服务端主动推送,省去了客户端很多个request请求带来的延时。并且这些push的资源客户端是可以缓存的,完全解决了Data URI scheme带来的问题。
但是server push可能有一些潜在的问题:
- 服务端不清楚客户端是否已经缓存资源,每次响应都push,导致浪费带宽
- 应用程序可能需要一些改动,让框架知道哪些资源需要push给客户端
HTTP/2带来的改变
有些HTTP/1中的优化(hack)在HTTP/2可能就不需要了:
- Domain Sharding:HTTP/2使用一个TCP连接,并且支持多路传输,可以不使用这个技术。在基于TLS的HTTP/2可能还会适得其反。
- Combine CSS, Image sprite, Resource Inlining:HTTP/2支持server push,所以这些方法可以不用了。
配置Nginx注意点
Nginx是对SPDY协议支持比较好的服务端,在Nginx1.5.10之后的版本开始支持SPDY 3.1,不支持server push特性,但是由于SPDY(HTTP/2)还是草稿,而且Nginx的SPDY模块也申明是实验性的支持SPDY,所以不推荐在生产环境中使用。
下文将介绍配置Nginx支持SPDY协议需要注意的事项。
1. 配置Nginx
Nginx中支持基于TLS的SPDY,或者基于明文TCP的SPDY。
配置基于明文的TCP,很简单,直接在listen语句后加上spdy即可。这种方式配置最简单,并且对客户端要求也最低。但是由于协议由HTTP变成SPDY,可能会导致网络设备失效,如防火墙,代理服务器等。
server {
listen 443 ssl spdy;
...
}
配置支持TLS的SPDY,先将ssl配置好,然后在listen后面加上"spdy"即可。由于将协议的改动封转在TLS中,网络设备对包的内容不可知,所以对网络设备基本没要求。
server {
listen 443 ssl spdy;
ssl_certificate server.crt;
ssl_certificate_key server.key;
...
}
注意:
- 如果使用基于TLS的SPDY,需要确认服务端安装的OpenSSL版本大于1.0.1(支持Next Protocol Negotiation)。
- 确认客户端支持NPN/ALPN。比如CocoaSPDY不支持NPN,所以没法使用基于TLS的SPDY,解决方案有两个:1.使用基于明文TCP的SPDY。2. 使用其他方法协商协议,需要另外写nginx模块。
2. 测试
如果可以被外放访问:可以使用这个网站查看是否正确:https://spdycheck.org/。
如果本地开发:可以使用chrome测试,在控制台中输入chrome.exe --use-spdy=no-ssl
,强制chrome仅使用SPDY协议。可以通过如下方法判断是否开启SPDY:打开chrome后,在地址栏输入:chrome://net-internals/#spdy,如果显示SPDY Enabled: true
并且Force SPDY Always: true
。
如果不是SPDY协议,网页会载入失败。使用时,如果配置使用明文TCP的SPDY,在地址栏输入"http://{hostname}:{port}",如果基于TLS的SPDY,在地址栏输入"https://{hostname}:{port}"即可。
总结
本文介绍了HTTP/2的背景,性能,发展情况,解释了HTTP/2引入的特点,对现有部署照成的影响,介绍了配置Nginx使用SPDY的注意事项。希望大家在HTTP/2真正落地后可以更快的体验到新协议带来的好处。
原文链接:http://www.gaott.info/http2-jie-shao/
作者:协思
出处:http://zeeman.cnblogs.com/
QQ交流群:32972862