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框架