http2 协议
HTTP/2 源自 SPDY/2,正式版http2规格标准叫做RFC 7540,发布于2015年5月15日。
HTTP/2 跟 SPDY 仍有不同的地方,主要是以下两点:
-
HTTP/2 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
-
HTTP/2 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DELEFT
http2 特点
http2 性能,http2 demo
-
HTTP/2’s binary framing layer
-
Streams, messages, and frames
-
Request and response multiplexing
-
Stream prioritization
-
One connection per origin
-
Flow control
-
Server push
-
Header compression
(1)二进制
HTTP/2 采用二进制格式传输数据
,而非 HTTP/1.x 的文本格式。二进制协议解析起来更高效。
(2)二进制格式
HTTP/1 的请求和响应报文,都是由起始行、首部和实体正文(可选)组成,各部分之间以文本换行符分隔。
HTTP/2 将请求和响应数据分割为更小的帧,并对它们采用二进制编码。
帧(Frame):HTTP/2 数据通信的最小单位。
消息(Message):指 HTTP/2 中逻辑上的 HTTP 消息。例如请求和响应等,消息由一个或多个帧组成
流(Stream):存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。
HTTP/2 中,同域名下所有通信都在单个连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。
Frame 是 HTTP/2 二进制格式的基础,Frame 的基本格式如下
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
字段含义可查看协议
(3)多路复用
HTTP/1.X 存在线端阻塞(head-of-line blocking)的问题。HTTP/1.1 试过用流水线(pipelining)来解决这个问题, 但是效果并不理想(数据量较大或者速度较慢的响应, 会阻碍排在他后面的请求)。HTTP 管道技术无法大规模使用。
多路复用,代替原来的序列和阻塞机制。就是所有的请求都是通过一个 TCP
连接并发完成。流支持优先级
和流量控制
。
HTTP/2 的多路复用特性,使得可以在一个连接上同时打开多个流,双向传输数据。每次请求/响应使用不同的 Stream ID。通过 Stream ID 标识,所有的请求和响应都同时跑在一条 TCP 链接上。 当流并发时,就会涉及到流的优先级和依赖。优先级高的流会被优先发送。图片请求的优先级要低于 CSS 和 SCRIPT,这个设计可以确保重要的东西可以被优先加载完。http2上面每个流都拥有自己的公示的流量窗口,它可以限制另一端发送数据。
(4)头压缩
HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,这会严重拖累发送请求的速度。因为它们需要等待带着ACK的响应回来以后,才能继续被发送。
HTTP/2 对消息头采用 HPACK (专为http2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。
(5)服务端推送
服务端可以在发送页面 HTML 时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求。
服务端可以主动推送,客户端也有权利选择接收与否。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收。
浏览器和web服务支持情况
安装部署
从 Nginx 1.9.5 开始,http_v2_module 已经替换了 ngx_http_spdy_module,安装版本用1.10.1
nginx
./configure --with-http_v2_module
mac
brew options nginx
brew install nginx --with-http2
配置https
HTTP/2 协议本身并没有要求必须基于 TLS 部署,但是 Chrome 和 Firefox 均表示只支持 HTTP/2 Over TLS。一方面更安全,希望保护以及尊重用户的隐私,一方面利用 TLS 的加密机制可以更好地穿透网络中间节点。需要先配置https。
# 创建一个私钥文件:
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl rsa -in server.key -out server_nopass.key
# 结合密钥和证书生成请求,创建一个自签署的CA证书
openssl req -new -x509 -days 3650 -key server_nopass.key -out server.crt
配置nginx
server
{
listen 443 ssl http2;
server_name www.kailian.com;
index index.php index.html;
root /data/web/www;
ssl on;
ssl_certificate /usr/local/etc/nginx/server.crt;
ssl_certificate_key /usr/local/etc/nginx/server_nopass.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
keepalive_timeout 70;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
charset utf-8;
location ~ .*\.php$
{
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
测试
ssllabs查看https配置是否够快
在 Chrome 地址栏输入chrome://net-internals/#http2
,打开 Chrome 自带的 HTTP/2 查看工具,可查看 HTTP/2 帧信息
Wireshark抓包查看