一些HTTP2笔记

HTTP 1.1发明以来发生了哪些变化

1.从几KB大小的消息,到几MB大小的消息

2.每个页面小于10个资源,到每页面100多个资源

3.从文本为主的内容,到富媒体(如图片,声音,视频)为主的内容

4.对页面内容实时性高要求的应用越俩越多

 

HTTP 1.1的高延迟问题

高延迟带来页面加载速度的降低

1.随着带宽的增加,延迟并没有显著下降

2.并发连接有限

3.同一连接同时只能在完成一个HTTP事务(请求/响应)才能处理下一个事务

 

高延迟VS高带宽

单连接上的串行请求

无状态导致的高传输量(低网络效率)

无状态特性带来的巨大HTTP头部

重复传输的体积巨大的http头部

特别是cookie

HTTP 1.1为了解决性能问题做过的努力

1.Spriting 合并多张小图为一张大图供浏览器JS切割使用

缺点:不能区别对待,一张小图的更改,整个大图需要重新传输

2.Inlining内联:将图片嵌入到CSS或者HTML文件中,减少网络请求次数

3.Concatenation拼接:将多个体积较小的js使用webpack等工具打包成1个体积更大的js文件

缺点:1个文件的改动导致用户重新下载多个文件

4.Sharding分片:将同一页面的资源分散到不同域名下,提升连接上限

 

HTTP 1.1不支持服务器推送消息

 

HTTP2 特性

SPDY(2012-2016 google)

HTTP2 (RFC7540 2015.5)

1.在应用层上修改,基于并充分挖掘TCP协议性能

2.客户端向server发送request这种基本模型不会变

3.老的scheme不会变,没有http2://

4.使用http 1.x的客户端和服务器可以无缝的通过代理方式转接到http 2.x上

5.不识别http 2的代理服务器可以将请求降级到http1.x

主要特性

传输数据量的大幅减少

1.以二进制方式传输

2.标头压缩

多路复用及相关功能

消息优先级

服务器的消息推送

 

HTTP2是不是必须基于TLS/SSL协议

1.IETF标准不要求必须基于TLS/SSL协议

2.浏览器要求必须基于TLS/SSL协议

(1).希望网络安全

(2).利用现有的TLS握手

3.在TLS层ALPN扩展做协商,只认HTTP 1.x的代理服务器不会干扰HTTP 2

4.schema: http://和https://默认基于80和443端口

5.h2:基于TLS协议运行的http 2被称为h2

6.h2c:直接在tcp协议之上运行的http 2被称为h2c

 

h2与h2c的区别

h2c:不使用TLS协议进行协议升级

客户端测试工具:curl (7.46.0版本及以上支持http 2)

curl http://nghttp/2.org -http/2 -v 

然后客户端还需要发送Magic帧

Preface(ASCII编码,12字节)

1.何时发送

接收到服务器发送来的101 Switching Protocols

TLS握手成功后

2.Preface内容

3.发送完毕后,应紧跟SETTING帧

h2:使用TLS协议进行协议升级

TLS通讯过程

1.验证身份

2.达成安全套件共识

3.传递密匙

4.加密通讯

NPN:(Next Protocol Negotiation)

SPDY使用的由客户端选择协议的NPN扩展

ALPN

在上面的做了改进,由客户端告诉支持哪些协议,服务器做一个选择

 

HTTP 2核心概念

1.连接Connection:1个TCP连接,包含一个或者多个stream

2.数据流stream:一个双向通讯数据流,包含一个或者多条Message

3.消息Message:对应HTTP 1中的请求或者响应,包含一条或者多条Frame

4.数据帧Frame:最小单位,以二进制压缩格式存放HTTP 1中的内容

Stream,Message,Frame间的关系

每一个stream都会有一个id标识,多个帧之间通过这个stream id对应起来

frame与message没有概念关联起来

消息的组成:Headers帧与Data帧

在wireshare中,每一个报文都是一个frame帧

传输中无序,接收时组装

不同的stream之间可以无序,但是同一个stream之间得是有序的

 

消息与帧

http 1.x中的一个请求或者响应就是一个message消息

http 2 中上图是一个帧, 是通过业务上的逻辑关系,一个stream中可以存在多个message,而一个message通过多个帧组成

帧格式:Steam ID的作用

实现多路复用的关键

1.接收端的实现可据此并发组装消息:

所以同一个id的不能无序,多个id的才能利用多路复用,

同一个id里面的多个frame是无法利用多路复用的。

要实现并发要新起一个stream

2.同一Stream内的frame必须是有序的(无法并发)

3.SETTINGS_MAX_CONCURRENT_STREAMS控制着并发stream数

推送依赖性请求的关键

1.由客户端建立的流必须是奇数

2.由服务器建立的流必须是偶数(一般是推送)

流状态管理的约束性规定

1.新建立的流ID必须大于曾经建立过的状态为opened或者reserved的流ID

2.在新建立的流上发送帧时,意味着将更小ID且为idle状态的流置位closed状态

3.Stream ID不能复用,长连接耗尽ID应创建新连接

应用层流控仅影响数据帧

1.stream ID为0的流仅用于传输控制帧

2.在HTTP 1升级到h2c中,以ID为1流返回响应,之后流进入half-closed(local)状态

 

帧格式

9字节标准帧头部:帧长度

1.0至2^14(16384) - 1

所有实现必须可以支持16KB以下的帧

2.2^14 至 2^24 - 1(16777215)

传递16KB到16MB的帧时,必须接受端首选公布自己可以处理此大小

通过SETTINGS_MAX_FRAME_SIZE帧(Identifier=5)告知

帧类型Type

Setting设置帧格式(type=0x4)

1,设置帧并不是协商,而是发送方向接收方通知其特性、能力

2.一个设置帧可同时设置多个对象

Identifier:设置对象

Value:设置值

Setting设置对象的类型

hpack压缩算法 

1.静态字典

2.动态字典

3.哈夫曼编码

第一次传输是完成的key-value,第二次传输的时候,发现只有path变了,其他的key-value都可以用索引表里面的数字来代替,

如下图

HPACK压缩比:h2load

节省空间61.94%

huffman编码

1.原理:出现概率较大的符号采用较短的编码,概率较小的符号采用较长的编码

2.静态huffman编码

 

3.动态huffman编码

 

服务端推送

提前将资源推送至浏览器缓存

特性:推送可以基于已发送的请求,例如客户端请求html,主动推送js文件

实现方式:1.推送资源必须对应一个请求 2.请求由服务端PUSH_PROMISE帧发送 3.响应在偶数ID的STREAM中发送

http1.1中获取html后,需要css资源时

浏览器触发:需要两次往返

PUSH_PROMISE方式

1.在stream1中通知客户端CSS资源即将来临

2.在stream2中发送css资源(stream1和stream2可以并发)

复杂点的例子

PUSH帧的格式

PUSH_PROMISE帧, type=0x5 只能由服务器发送

PUSH推送模式的禁用

SETTINGS_ENABLE_PUSH(0x2)

1表示启用推送功能

0表示禁用推送功能

 

stream流状态变迁

stream特性:

1.一条tcp连接上,可以并发存在多个处于Open状态的stream

2.客户端或者服务器都可以创建新的stream

3.客户端或者服务器都可以首先关闭stream

4.同一条stream内的frame帧 是有序的

5.从stream ID的值可以轻易分辨PUSH消息

所有为发送header/data 消息而创建的流,从1,3,5等递增奇数开始

所有为发送PUSH消息而创建的流,从2,4,6等递增偶数开始

Message特性:

1.一条http message由1个header(可能含有0个或者多个持续帧构成)及0个或者多个DATA帧构成

2.header消息同时包含http 1.1中的start line与headers部分

3.取消http 1.1中的不定长chunk消息

Get消息发送示例

Post消息发送示例

stream流的状态

1.帧符号

   H:headers帧

   PP:PUSH_PROMISE帧

   ES:END_STREAM标志位

   R:RST_STREAM帧

2.流状态      

idle:起始状态

closed

open:可以发送任何帧

half closed :单向关闭

   remote:不再接收数据帧

   local:不能再发送数据帧

reserved:

remote

local

RST_STREAM帧(type=0x3)

http2多个流共享同一个连接,RST帧允许立刻终止一个未完成的流

RST_STREAM帧不使用任何flag

RST_STREAM帧的格式

常见错误码

Stream优先级与资源分配规则

Priority优先级设置帧

1.帧类型 type=0x2

2.不使用flag标志位字段

3.Stream Dependency:依赖流

4.Weight权重:取值范围1-256,默认权重16

5.仅针对stream流,若id为0试图影响连接,则接收端必须报错

6.在idle和closed状态下,仍然可以发送Priority帧

数据流优先级

12+4 = 16  12/16 4/16   分配内存,buffer

只有D完成后,才能去做C,这时候的D和C优先级没有用

这种A和B的优先级才有用

E和C ,A和B

exclusive标志位

E为0

B和C依赖A, E为0时,D依赖A

E为1

B和C依赖A,E为1时,D独占,D依赖A,B和C依赖D

http2 流量控制

http 1.1由tcp层进行流量控制

前提:http1的tcp连接上没有多路复用、

http2需要应用层控制

 问题:

1.多stream争夺tcp的流控制,互相干扰可能造成stream阻塞

2.代理服务器内存有限,上下游网速不一致时,通过流控管理内存

http2中的流控制既针对单个stream,也针对整个tcp连接

1.客户端与服务器都具备流量控制能力

2.单向流控制:发送和接收独立设定流量控制

3.以信用为基础:接收端设定上限,发送端应当遵循接收端发出的指令。

4.流量控制窗口(流或者连接)的初始值是65535字节

5.只有DATA帧服从流量控制

6.流量控制不能被禁用

window_update帧

1.type=0x8,不使用任何flag

2.窗口范围是1- 2^31 -1 (2147483647)字节

 0是错误的,接收端应该返回PROTOCOL_ERROR

3.当stream ID为0时表示对连接流控,否则为对stream流控

4.流控仅针对直接建立tcp连接的两端

  代理服务器并不需要透传window_update帧

  接收端的缩小流控窗口会最终传递到源发送端

流控制窗口

1.窗口大小由接收端告知

2.窗口随着DATA帧的发送而减少

SETTINGS_MAX_CONCURRENT_STREAMS并发流

1.并发仅统计open或者half-close状态的流(不包含用于推送和的reserved状态)

2.超出限制后的错误码

PROTOCOL_ERROR

REFUSED_STREAM

http2与gRPC框架

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章