HTTP2特性预览和抓包分析,周详解析HTTP

by admin on 2019年2月6日

一分钟预览 HTTP2 特性和抓包分析

2016/09/26 · JavaScript
· HTTP/2

原稿出处: 段隆贤   

背景

近年来,http互联网请求量日益增进,以下是httparchive计算,从2012-11-01到2016-09-01的央求数量和传导大小的倾向图:

必发88 1

眼下大部分份客户端&服务端架构的应用程序,都是用http/1.1老是的,现代浏览器与单个域最安卡拉接数,都在4-6个左右,由上图Total
Requests数据,若是不用CDN分流,平均有20个左右的串行请求。
HTTP2
是1999年发表http1.1后的两次首要的改进,在情商层面改良了上述难题,减弱资源占用,来,直接感受一下差别:

HTTP/2 is the future of the Web, and it is
here!
那是 Akamai 集团创建的一个法定的以身作则,用以声明 HTTP/2 比较于事先的
HTTP/1.1 在性质上的石破天惊进步。 同时请求 379 张图片,从Load time
的自查自纠可以看来 HTTP/2 在进程上的优势。

必发88 2

正文所有源码和抓包文件在github

http2 协议

HTTP/2 源自 SPDY/2,正式版http2规格标准叫做RFC
7540,公布于二零一五年五月15日。

  • RFC 7540 – Hypertext Transfer Protocol Version 2
    (HTTP/2)

  • RFC 7541 – HPACK: Header Compression for
    HTTP/2

  • fex-team翻译的 htt2
    中国和英国文对照.md)

HTTP/2 跟 SPDY 仍有例外的地点,紧假若以下两点:

  1. HTTP2特性预览和抓包分析,周详解析HTTP。HTTP/2 协助明文 HTTP 传输,而 SPDY 强制行使 HTTPS

  2. HTTP/2 新闻头的压缩算法采纳 HPACK,而非 SPDY 接纳的 DELEFT

初稿地址

背景

新近,http互连网请求量日益拉长,以下是httparchive计算,从2012-11-01到2016-09-01的请求数量和传导大小的大势图:

必发88 3

 

此时此刻多数份客户端&服务端架构的应用程序,都是用http/1.1老是的,现代浏览器与单个域最达累斯萨拉姆接数,都在4-6个左右,由上图Total
Requests数据,假使不用CDN分流,平均有20个左右的串行请求。
HTTP2
是1999年发表http1.1后的四次紧要的改进,在商事层面改良了以上难点,裁减资源占用,来,直接感受一下差距:

HTTP/2 is the future of the Web, and it is
here!
那是 Akamai 公司成立的一个法定的以身作则,用以评释 HTTP/2 比较于事先的
HTTP/1.1 在性质上的巨大提高。 同时呼吁 379 张图片,从Load time
的对待能够见见 HTTP/2 在进度上的优势。

必发88 4

 

本文所有源码和抓包文件在github

HTTP/2 源自 SPDY/2

SPDY 种类协议由谷歌(谷歌(Google))开发,于 2009 年堂而皇之。它的设计目的是下落 50%
的页面加载时间。当下广大尽人皆知的互连网商家都在自己的网站或 APP 中选用了
SPDY 种类协议(当前前卫版本是
SPDY/3.1),因为它对质量的升级是肯定的。主流的浏览器(谷歌、火狐、Opera)也都早已经支撑
SPDY,它已经化为了工业标准,HTTP Working-Group 最终决定以 SPDY/2
为底蕴,开发 HTTP/2。HTTP/2标准于二零一五年12月以RFC 7540正规发布。

但是,HTTP/2 跟 SPDY 仍有例外的地点,紧假若以下两点:

HTTP/2 帮助明文 HTTP 传输,而 SPDY 强制行使 HTTPS
HTTP/2 音信头的压缩算法采取 HPACK ,而非 SPDY 选用的 DEFLATE(感谢网友
逸风之狐指正)

协商文档请见:rfc7540:HTTP2

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...)                      ...
+---------------------------------------------------------------+

字段含义可查看协议

必发88 5

http2.png

(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 帧来拒收。

写在前面

超文本传输协议(英文:HyperText Transfer
Protocol,缩写:HTTP)是网络上选拔最为普遍的一种互连网协议。设计 HTTP
最初的目标是为着提供一种公布和接到 HTML 页面的章程。通过 HTTP 或者 HTTPS
协议请求的资源由联合营源标识符(URI)来标识。

即便HTTP/1.1祥和运行了十多年了,但HTTP/2来势汹涌,作为技术工程师有要求学习一下HTTP/2。前日,阿里云CDN安防技术专家金九将从历史、特性、调试、质量多个层面,来宏观解析HTTP/2,希望本文可以给您带来一些启示。


HTTP/2 源自 SPDY/2

SPDY 体系协议由谷歌(谷歌(Google))开支,于 2009 年堂而皇之。它的筹划目的是下落 50%
的页面加载时间。当下众多有名的网络集团都在温馨的网站或 APP 中动用了
SPDY 体系协议(当前风靡版本是
SPDY/3.1),因为它对质量的升官是鲜明的。主流的浏览器(谷歌(Google)、火狐、Opera)也都早已经援助SPDY,它已经成为了工业标准,HTTP Working-Group 最后决定以 SPDY/2
为根基,开发 HTTP/2。HTTP/2标准于二零一五年十月以RFC 7540规范刊出。

而是,HTTP/2 跟 SPDY 仍有两样的地点,首要是以下两点:

HTTP/2 接济明文 HTTP 传输,而 SPDY 强制行使 HTTPS
HTTP/2 音信头的压缩算法选用 HPACK ,而非 SPDY 选用的 DEFLATE(感谢网友
逸风之狐指正)

商讨文档请见:rfc7540:HTTP2

HTTP2特性概览

浏览器和web服务支撑意况

http2
帮忙清单

一、历史

1、 HTTP/0.9
最早的原型,1991年揭晓,该版本极其简约,只扶助 GET 方法,不襄助 MIME
类型和各样 HTTP 首部等等。

2、 HTTP/1.0
1996年揭示。HTTP/1.0在HTTP/0.9的基础之上添加很多格局,各类 HTTP
首部,以及对多媒体对象的拍卖。

除此之外GET命令,还引入了POST命令和HEAD命令,足够了浏览器与服务器的并行手段。

HTTP2特性预览和抓包分析,周详解析HTTP。其它格式的情节都得以发送。那使得网络不但可以传输文字,仍能传输图像、摄像、二进制文件。那为互连网的大进步奠定了基础。

HTTP请求和回答的格式也变了。除了数量部分,每一趟通讯都无法不概括头音信(HTTP
header),用来讲述一些元数据。

可以说,HTTP/1.0是对HTTP/0.9做了开拓性的更改,但HTTP/1.0仍旧有部分缺点,其重大缺点是种种TCP连接只可以发送一个呼吁,发送数据完结后延续就关门,若是还要伸手其余资源,就得再新建一个接连。尽管有些浏览器为了化解这些标题,用了一个非标准的Connection尾部,但以此不是业内底部,各样浏览器和服务器达成有可能不平等,由此不是常有解决办法。

3 、HTTP/1.1
1999年标准颁发。HTTP/1.1是眼下主流的 HTTP 协议。完善了后面 HTTP
设计中的结构性缺陷,明确了语义,添加和删除了部分特性,协助更加复杂的的
Web 应用。

通过了十多年将近20年的开拓进取,那么些本子的HTTP协议已经很平静了,跟HTTP/1.0比照,它新增了广大备受瞩目标新特色,比如Host协议头、Range分段请求、默许持久连接、压缩、分块传输编码(chunked)、缓存处理等等,至今都大方利用,而且许多软件看重这几个特征。

即便HTTP/1.1并不像HTTP/1.0对此HTTP/0.9那样的革命性,不过也有成百上千增高,近年来主流浏览器均默许使用HTTP/1.1。

# 4、SPDY
SPDY(发音:speedy)协议由谷歌(Google)开发,主要解决 HTTP/1.1
功效不高的题材,于二〇〇九年公开,到二〇一六年底停止职务。因为HTTP/2已经被IETF标准化了,未来各个新版浏览器都会支持HTTP/2,谷歌(Google)认为SPDY已经远非存在的必需了,接下去的任务由HTTP/2去完结。

5、HTTP/2
HTTP/2是风靡的HTTP协议,已于二〇一五年七月份业内公布, Chrome、
IE11、Safari以及Firefox 等主流浏览器已经支撑 HTTP/2商讨。

瞩目是HTTP/2而不是HTTP/2.0,这是因为IETF(Internet Engineering Task
Force,网络工程职分组)认为HTTP/2已经很成熟了,没有须求再公布子版本了,将来只要有根本变更就直接揭橥HTTP/3。

实质上,HTTP/2的前身是SPDY,甚至它俩的靶子、原理和骨干完成都大概。IETF组委会中有无数谷歌(Google)工程师,将SPDY牵动成为正式也就欠缺为奇了。

HTTP/2不仅优化了品质而且非常了HTTP/1.1的语义,其几大特点与SPDY差不离,与HTTP/1.1有英雄差异,比如它不是文本协议而是二进制协议,而且HTTP尾部拔取HPACK举行压缩,接济多路复用、服务器推送等等。


HTTP2特性概览

1. 二进制协议

HTTP/2 接纳二进制格式传输数据,而非 HTTP/1.x 的文本格式

必发88 6

由上图可以看出HTTP2在原本的应用层和HTTP层添加了一层二进制传输。

二进制协议的一个好处是,可以定义额外的帧。

HTTP/2
定义了近十种帧(详情可分析抓包文件),为未来的高级应用打好了根基。若是应用文本落成那种效益,解析数据将会变得极度麻烦,二进制解析则有利于得多。
RFC7540:Frame
Definitions
必发88 7
合计中定义的帧

安装配置

从 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

二、特性

1、二进制协议

HTTP/2
采纳二进制格式传输数据,而非HTTP/1.x的文本格式。新闻头和音信体均选拔二进制格式,并号称”帧“(Frame)。Frame二进制基本格式如下(摘自rfc7540#section-4.1):

+———————————————–+
| Length (24) |
+—————+—————+—————+
| Type (8) | Flags (8) |
+-+————-+—————+——————————-+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0…) …
+—————————————————————+

就此说是宗旨格式,是因为具有HTTP/2
Frame都是由该宗旨格式来封装,类似于TCP头,近来有10个Frame,由Type字段来不一致,各类Frame都有谈得来的二进制格式,都封装Frame
Payload中。

里面有多个重点的Frame:Headers Frame(Type=0x1)和Data
Frame(Type=0x0),分别对应HTTP/1.1中的音讯头(Header)和消息体(Body),不问可知语义并不曾太大转变,而是文本格式变成二进制的Frame。二者的转换和涉嫌如下图(摘自
《High Performance Browser Networking》):

必发88 8

此外,HTTP/2中还有流(Stream)和消息(Message)的概念,通过Stream
Identifier(即流ID)字段来标识,流ID一样的是同一个流,流中隐含音信,那个消息对应HTTP/1.x的请求音信(Request
Message)或者响应音信(Response
Message),新闻是因此帧(Frame)来传输的,响应新闻相比较大,可能由多少个Data
Frame来传输。HTTP/2中流、音信和帧的附和关系如下图(摘自 《High
Performance Browser Networking》):

必发88 9

2、底部压缩

HTTP/1.x 每回请求和响应,都会带走大批量冗余音信头新闻,比如Cookie和User
Agent,基本均等的始末,每一回请求浏览器都会默许指导,那会浪费广大带宽资源,也潜移默化了快慢。那是因为HTTP是无状态协议,每一回请求都必须附上所有音信,从而导致了历次请求都带上多量再一次的新闻头。

为此,HTTP/2做了优化,对新闻头接纳HPACK格式举行压缩传输,并对音信头建立索引表,相同的音信头只发送索引号,从而升高成效和进程。但付出的代价是客户端和服务器均维护一个索引表,在现在内存不值钱的时代,这一点空间换取时间或者非常值得的。

关于HPACK请参考RFC7541。

3、多路复用

多路复用是指在一个TCP连接里,客户端和服务器都得以同时发送四个请求或者响应,对HTTP/1.x的话各样请求和响应都是有严酷的次第须要,而在HTTP/2中,不用根据次序一一对应,而且出现的八个请求或者响应中其它一个伸手阻塞了不会影响其余的乞求或者响应,这样就幸免了“队头堵塞”。如下图(摘自
《High Performance Browser Networking》):
必发88 10

4、服务器推送

服务器推送(Server
Push)是指在HTTP/2中服务器未经请求可以积极给客户端推送资源。例如服务端能够主动把
图片、JS 和 CSS
文件推送给浏览器,而不需求浏览器解析HTML后再发送这个请求。当浏览器解析HTML后那一个须求的资源都已经在浏览器里了,大大升高了网页加载的进程。如下图(摘自
《High Performance Browser Networking》):

必发88 11

浏览器发起呼吁page.html这么些页面,那一个页面中引用了script.js和style.css,服务器在响应page.html后捎带推送了script.js和style.css那五个公文,那样浏览器解析完page.html后发觉引用的script.js和style.css已经在当地了,不须要再发送请求了,这样就节约了五遍呼吁和那五次呼吁所花的网络时间,大大升高了网络品质和用户体验。

5、安全

HTTP的河池是由SSL/TLS来维系,也就是HTTPS,其实HTTP/2并不强制须要重视SSL/TLS,但是,当前主流浏览器均只帮衬基于SSL/TLS的HTTP/2,况且在互连网吓唬日益跋扈的网络环境下,HTTPS将是鹏程的势头,HTTP/2基于HTTPS也是前景的大势,而各大主流浏览器在落到实处HTTP/2之初均只协理SSL/TLS的HTTP/2,可见安全也是HTTP/2的要害特色之一。


1. 二进制协议

HTTP/2 选拔二进制格式传输数据,而非 HTTP/1.x 的文本格式

必发88 12

 

由上图可以看到HTTP2在原来的应用层和HTTP层添加了一层二进制传输。

二进制协议的一个利益是,可以定义额外的帧。

HTTP/2
定义了近十种帧(详情可分析抓包文件),为未来的尖端应用打好了根基。如若应用文本达成那种功用,解析数据将会变得那个辛勤,二进制解析则有利得多。
RFC7540:Frame Definitions

必发88 13

商事中定义的帧

2. 多路复用

HTTP/2
复用TCP连接,在一个连连里,客户端和浏览器都足以而且发送多少个请求或答复,而且不用根据顺序依次对应,那样就幸免了”队头堵塞”(见TCP/IP详解卷一)。
每个 Frame Header 都有一个 Stream ID
就是被用于落到实处该特性。每一回请求/响应使用分歧的 Stream ID。就好像同一个 TCP
链接上的数量包通过 IP: PORT 来分别出多少包去往何地一样。
必发88 14

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.

配置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;
    }

}

三、调试

从常理和目的上看HTTP/2和SPDY差不离,从Nginx官方代码上看HTTP/2和SPDY的贯彻也基本上。Nginx官方代码中早就去除了spdy模块的代码,取而代之的是http2模块(ngx_http_v2_module)。

1、启用

1.1、在编译参数中加入http2模块(默许已经有ssl模块了):

# git clone https://github.com/alibaba/tengine.git
# cd tengine
# ./configure --prefix=/opt/tengine --with-http_v2_module
# make
# make install

1.2、生成测试表明和私钥

# cd /etc/pki/CA/
# touch index.txt serial
# echo 01 > serial
# openssl genrsa -out private/cakey.pem 2048
# openssl req -new -x509 -key private/cakey.pem -out cacert.pem
# cd /opt/tengine/conf
# openssl genrsa -out tengine.key 2048
# openssl req -new -key tengine.key -out tengine.csr
...
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Aliyun
Organizational Unit Name (eg, section) []:CDN
Common Name (e.g. server FQDN or YOUR name) []:www.tengine.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
...
# openssl x509 -req -in tengine.csr -CA /etc/pki/CA/cacert.pem -CAkey /etc/pki/CA/private/cakey.pem -CAcreateserial -out tengine.crt

1.3、配置http2

server {
        listen       443 ssl http2; 
        server_name  www.tengine.com;
        default_type  text/plain;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_certificate     tengine.crt;
        ssl_certificate_key tengine.key;
        ssl_ciphers         EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:EECDH+AES256:EECDH+3DES:RSA+3DESi:RC4-SHA:ALL:!MD5:!aNULL:!EXP:!LOW:!SSLV2:!NULL:!ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers  on;

        location / {
            return 200 "http2 is ok";
        }
    }

1.4、启动tengine即可:

# /opt/tengine/sbin/nginx -c /opt/tengine/conf/nginx.conf
1.5、测试
先绑定/etc/hosts:
127.0.0.1 www.tengine.com
用nghttp工具测试:
jinjiu@j9mac ~/work/pcap$ nghttp 'https://www.tengine.com/' -v
[  0.019] Connected
[  0.043][NPN] server offers:
          * h2
          * http/1.1
The negotiated protocol: h2
[  0.064] recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
          (niv=3)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):2147483647]
          [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
[  0.064] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
          (window_size_increment=2147418112)
[  0.064] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
          (niv=2)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.064] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.064] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  0.064] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  0.077] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  0.077] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  0.077] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
[  0.077] send HEADERS frame <length=39, flags=0x25, stream_id=13>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /
          :scheme: https
          :authority: www.tengine.com
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.9.2
[  0.087] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.087] recv (stream_id=13) :status: 200
[  0.087] recv (stream_id=13) server: Tengine/2.2.0
[  0.087] recv (stream_id=13) date: Mon, 26 Sep 2016 03:00:01 GMT
[  0.087] recv (stream_id=13) content-type: text/plain
[  0.087] recv (stream_id=13) content-length: 11
[  0.087] recv HEADERS frame <length=63, flags=0x04, stream_id=13>
          ; END_HEADERS
          (padlen=0)
          ; First response header
http2 is ok[  0.087] recv DATA frame <length=11, flags=0x01, stream_id=13>
          ; END_STREAM
[  0.087] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])

用chrome浏览器测试:
必发88 15

2、抓包分析

从抓包来读书HTTP/2格式是最好的主意,但HTTP/2又是基于https的,也就是加密的,直接抓包看到的是密文,没有意义,还好Wireshark提供解密https流量的章程可以相比便利地调试HTTP/2。

2.1、初始出种类变量$SSLKEYLOGFILE,以OSX系统为例

#bash
echo "\nexport SSLKEYLOGFILE=~/ssl_debug/ssl_pms.log" >> ~/.bash_profile && . ~/.bash_profile

2.2、打开Chrome或者Firefox

#chrome
open /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome 
#firefox
open /Applications/Firefox.app/Contents/MacOS/firefox

用打开的Chrome或者Firefox浏览器打开https网站,比如:https://www.taobao.com
接下来看看文件~/ssl_debug/ssl_pms.log有没有内容,有内容就可以用Wireshark解密https数据了。

2.3、Wireshark设置

Wireshark->Perferences...->Protocols->SSL

启航抓包:
必发88 16

必发88 17

看得出曾经能得到HTTP/2的公然数据了。篇幅所限,在此不进行具体细节了,更加多HTTP/2二进制协议细节请参考RFC7540。


2. 多路复用

HTTP/2
复用TCP连接,在一个一而再里,客户端和浏览器都足以同时发送多个请求或答复,而且不用依照顺序依次对应,那样就幸免了”队头堵塞”(见TCP/IP详解卷一)。
每个 Frame Header 都有一个 Stream ID
就是被用于落到实处该特性。每趟请求/响应使用分化的 Stream ID。就像同一个 TCP
链接上的数码包通过 IP: PORT 来不相同出多少包去往哪里一样。

必发88 18

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.

3. 数据流

数量流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),废除以此数据流。1.1版裁撤数据流的唯一情势,就是关门TCP连接。那就是说,HTTP/2
可以撤除某一回呼吁,同时有限协助TCP连接还打开着,可以被别的请求使用。

测试

chrome插件

ssllabs查阅https配置是还是不是够快

在 Chrome 地址栏输入chrome://net-internals/#http2,打开 Chrome 自带的
HTTP/2 查看工具,可查阅 HTTP/2 帧音讯

Wireshark抓包查看

四、性能

测试机器配置:cache1.cn1, 115.238.23.13, 16核AMD(R) Xeon(R) CPU L5630
@ 2.13GHz,48G内存,万兆网卡
测试工具:h2load
测试结果:

必发88 19

必发88 20


3. 数据流

多少流发送到一半的时候,客户端和服务器都足以发送信号(RST_STREAM帧),撤除以此数据流。1.1版打消数据流的唯一办法,就是关闭TCP连接。那就是说,HTTP/2
可以收回某两次呼吁,同时保障TCP连接还开辟着,能够被别的请求使用。

必发88 ,4. 头音信压缩:

HTTP/2 对音信头选拔
HPACK
进行削减传输,可以节约消息头占用的网络的流量。而 HTTP/1.x
每一次请求,都会带走多量冗余头新闻,浪费了众多带宽资源。
HTTP2对http头建立索引表,相同的头只发送hash
table 的index, 同时还用了霍夫曼编码和传统的gzip压缩。

相关资料

  • http2
    讲解

  • http2 home

  • http2
    专题

  • 【协议分析】HTTP2优势分析

结论

1、无论是还是不是keepalive,HTTP/2与SPDY/3.1质量相当,HTTP/2略优。
2、在size为1k、2k、4k测试结果中维系较低RT情形下QPS也较高,CPU没有高达瓶颈,加大压测客户端数量后QPS有所升高,但RT变大,5xx也变多(那有些数目尚未交给,是测试时记下的场景)。
在size为16k、32k、64k、128k、256k的测试结果中CPU达到瓶颈,随着size变大,QPS下跌,RT变高,CPU质量消耗较多的函数是gcm_ghash_clmul。
在size为512k时网卡达到瓶颈,CPU没有达标瓶颈。
3、在拉开keepalive的情事下,HTTP/1.1的习性与HTTP/2的特性差别不是很大。但关闭keepalive时HTTP/2的属性比HTTP/1.1更好。

初稿地址

必发88 21
 

4. 头音信压缩:

HTTP/2 对音信头采纳
HPACK
举行削减传输,可以节省音信头占用的互联网的流量。而 HTTP/1.x
每便请求,都会带走大批量冗余头音信,浪费了好多带宽资源。
HTTP2对http头建立索引表,相同的头只发送hash
table 的index, 同时还用了霍夫曼编码和历史观的gzip压缩。

5. 服务器推送

服务端可以更快的把资源推送给客户端。例如服务端可以积极把 JS 和 CSS
文件推送给客户端,而不须求客户端解析 HTML
再发送这么些请求。当客户端须要的时候,它早已在客户端了。

那就是说存在一个题材,假如客户端设置了缓存咋做。有三种办法(来自社区)

  • 客户端可以由此设置SETTINGS_ENABLE_PUSH为0值布告服务器端禁用推送
  • 意识缓存后,客户端和服务器都足以发送信号(RST_STREAM帧),打消这几个数据流。
  • cache-digest(提案)

    rfc7540: HTTP2 Server
    Push

    #### 6. 流优先级

    HTTP2允许浏览器指定资源的先期级。

    rfc7540: Stream
    Priority

5. 服务器推送

服务端可以更快的把资源推送给客户端。例如服务端可以积极把 JS 和 CSS
文件推送给客户端,而不要求客户端解析 HTML
再发送这么些请求。当客户端必要的时候,它早已在客户端了。

那么存在一个题材,若是客户端设置了缓存如何是好。有三种办法(来自社区)

  • 客户端可以经过设置SETTINGS_ENABLE_PUSH为0值公告服务器端禁用推送
  • 意识缓存后,客户端和服务器都得以发送信号(RST_STREAM帧),撤除以此数据流。
  • cache-digest(提案)

    rfc7540: HTTP2 Server
    Push

    #### 6. 流优先级

    HTTP2允许浏览器指定资源的先期级。

    rfc7540: Stream
    Priority

浏览器支持

必发88 22

主流浏览器都只接济 HTTP/2 Over TLS

浏览器援救

主流浏览器都只支持 HTTP/2 Over TLS

node中启用http2

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了。

请求头和响应头:
必发88 23

证实:新版的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 
})

源码在github

响应

必发88 24

必发88 25

node中启用http2

node中得以用spdy模块来启动应用,spdy的api,与https是同等的且主流浏览器只接济HTTP/2
Over TLS,须要配备 私钥和表明,本地自签定服务器配置可参考引用6,7

JavaScript

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 . You can
open the URL in the browser.`) } ) app.use(“/”,(req,res)=>{
res.send(“hello http2!”); })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

JavaScript

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 })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
})

源码在github

响应

抓包分析

可以用chrome
内部自带的工具(chrome://net-internals/)查看http2流量,但这一个包音讯量相比少,结构不如大家耳熟能详的Fiddler%E6%9F%A5%E7%9C%8Bhttp2%E6%B5%81%E9%87%8F,%E4%BD%86%E8%BF%99%E4%B8%AA%E5%8C%85%E4%BF%A1%E6%81%AF%E9%87%8F%E6%AF%94%E8%BE%83%E5%B0%91%EF%BC%8C%E7%BB%93%E6%9E%84%E4%B8%8D%E5%A6%82%E6%88%91%E4%BB%AC%E7%86%9F%E6%82%89%E7%9A%84Fiddler)
or Wireshark清晰。

Fiddler是直接当做中间代理,可以看做客户端直接与服务端通信,可以像浏览器那样直接解密https,直接看到https报文,
而是由于受限于.NET
Framework暂不扶助Http2.

用wireshark直接抓包 https:443端口的流量是那样的:
必发88 26

多少被加密了,协议细节完全看不到。
这里介绍了一种艺术获得私钥解包。
抓包https包时要把代理关了,不然私钥不是同一个,wireshark不可以解包(被那么些坑了两时辰T
T)。

必发88 27

必发88 28

一个包内有三个不等的Steam ID

必发88 29

追踪解密后TCP流可以看看,由于多路复用,各样差别的哀告交替传输分化的帧,所以流数据是乱的。但在一如既往帧内数据或者正常的。

抓包分析

可以用chrome
内部自带的工具(chrome://net-internals/)查看http2流量,但以此包音讯量比较少,结构不如大家熟识的Fiddler%E6%9F%A5%E7%9C%8Bhttp2%E6%B5%81%E9%87%8F,%E4%BD%86%E8%BF%99%E4%B8%AA%E5%8C%85%E4%BF%A1%E6%81%AF%E9%87%8F%E6%AF%94%E8%BE%83%E5%B0%91%EF%BC%8C%E7%BB%93%E6%9E%84%E4%B8%8D%E5%A6%82%E6%88%91%E4%BB%AC%E7%86%9F%E6%82%89%E7%9A%84Fiddler)
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

最后

最后,HTTP2有更高的传输速度,更少的资源占用,可以去除各样品质优化tricks(如css
sprite,inline-image.)
倒车WEB开发的美好未来T.T

参考资料

  1. Turn-on HTTP/2 today!
  2. Hypertext Transfer Protocol Version 2
    (HTTP/2)
  3. npm spdy
  4. npm spdy push
  5. How to create a self-signed SSL
    Certificate
  6. HPACK: Header Compression for
    HTTP/2
  7. 用Node.js成立自签署的HTTPS服务器

参考资料

  1. Turn-on HTTP/2 today!
  2. Hypertext Transfer Protocol Version 2
    (HTTP/2)
  3. npm spdy
  4. npm spdy push
  5. How to create a self-signed SSL
    Certificate
  6. HPACK: Header Compression for
    HTTP/2
  7. 用Node.js创造自签署的HTTPS服务器

    1 赞 收藏
    评论

必发88 30

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图