一 介绍
[classic_tong @ https://www.cnblogs.com/hugetong/p/12694322.html]
为了解决HTTP1的性能问题,HTTP2出现了。
http1有什么问题
1. 半双工的。请求与回应一来一回,彼此等待对方到底。
2. 不能并发,一个TCP隧道只能处理一个 请求回应 队列。
3. 隧道利用率低。大部分TCP连接,握手之后只通讯一次就结束了。
http2有什么新的
1. 在传输层与应用层直接,增加分帧层。
2. 增加流控制。
3. 增加服务器推送。
4. 增加头压缩。
二 分帧层
分帧层功能
1 分帧层使半双工变成了全双工。
2 分帧层在传输层之上实现了多条全双工隧道。
3 隧道支持优先级。
分帧层模型
为了实现多个全双工隧道的功能,引入以下三个概念:
1. 流 stream
2. 消息 message
3. 帧 frame
参考: https://developers.google.com/web/fundamentals/performance/http2?hl=zh-cn
三 包格式
应用层,也就是分帧层之上的一层。在逻辑结构和内容上,与http1相同。具体实现上有所差别。
帧结构
+-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+
详见: https://tools.ietf.org/html/rfc7540#section-4.3
四 头压缩
HEADER就是HTTP中的HEADER,它是有压缩的。
第一步,把常用的header name + value 用数组进行了替换,使用查表的方式进行约定,
表在这里: https://tools.ietf.org/html/rfc7541#appendix-A
后七个bit查表,第一个bit恒为1
0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 1 | Index (7+) | +---+---------------------------+
表中没有约定的内容,仍然使用ascii码的形式。
第二步,使用哈夫曼编码进行字符压缩。当然,其实也可以直接ascii码,说的有点乱,详见:https://tools.ietf.org/html/rfc7541#section-5.2
有三种情况:with indexing, without indexing, and never indexed, 格式类似,但是不完全相同。
第一种情况的格式是这样的:
0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 1 | Index (6+) | +---+---+-----------------------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length octets) | +-------------------------------+
要点:1 第二个bit是1代表当前这种情况。2 第9个bit是1代表后边的内容使用哈夫曼编码,如果是0直接使用ascii码。
举个例子: server: nginx
这个例子里,第三到第八个bit,查前文“第一步”里面的表,可以得到代表server的index值。填进去,在这里,它是54,加上第二个bit的1,16进制就是0x76。
如下图:
如图,0x76 84 aa 63 55 e7
76分析过了。84第一个bit是1,代表使用哈夫曼编码,去掉1剩下的4代表长度4个字节。后边的是个字节,就是哈夫曼编码。
可以通过查表得到,是另一张表,在这:https://tools.ietf.org/html/rfc7541#appendix-B
字符串nginx查表结果二进制:(后边的两个 11 是padding)
我们的例子里的二进制,是这样的。两个对照,是一致的。
以上。header的编码就是酱紫。
五 举个例子
http2c.pcap
使用nginx + hghttp2工具实验,抓到的包,截图在这里:
六 与SPDY的区别
1 SPDY是用控制与数据两种帧类型,HTTP2只使用一种。
2 HTTP2使用哈夫曼编码压缩,SPDY使用基于流的压缩。
来自wiki:https://en.wikipedia.org/wiki/HTTP/2#Genesis_in_and_later_differences_from_SPDY
七 完
[classic_tong @ https://www.cnblogs.com/hugetong/p/12694322.html]