协思

协作、思考、感悟、进步

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  39 Posts :: 4 Stories :: 18 Comments :: 0 Trackbacks

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等),状态码,头信息等。

目前浏览器的支持情况

Alt pic

CanIUse

服务端支持情况

  • Apache mod_spdy
  • Nginx (不支持server push)
  • Jetty Web Server
  • node-spdy
  • ……

厂商支持情况

  • Google
  • Twitter
  • Wordpress.com
  • LINE
  • Amazon Kindle Fire
  • Facebook
  • Akamai
  • Cloudflare
  • ……

性能改善情况

google选取了TOP 25网站进行测试,结果显示基于明文TCP的SPDY页面载入时间减少了27%~60%,基于SSL的SPDY页面载入时间减少了39%~55%。

Alt pic

spdy白皮书

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长连接,支持优先级的多路传输

这句话包括三个关键点:

  1. 一个TCP长连接:由于TCP建立连接慢的特点,每个请求都重新建立新的TCP连接是十分浪费的,所以HTTP/1.1中有了keepalive参数。虽然有了keepalive,但是有会Head-of-line blocking问题,即第一个响应慢了,会影响到后面所有的响应。于是HTTP/2支持在这个TCP连接中进行多路传输。

  2. 多路传输:HTTP/2中“请求-响应”称为一个stream,一个完整的stream由若干个frame组成,因此frame可以交错地传输。每个frame中带有一个streamId以标记属于哪个stream,奇数的id表示从客户端发的,偶数的id表示从服务端发的。

Alt pic

  1. 优先级: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/

 

posted on 2015-08-20 14:58  协思  阅读(188)  评论(0编辑  收藏