由于语雀转社区的图片有防盗链,暂时没解决(有方案)。语雀的格式更友好:https://www.yuque.com/docs/share/a827dce3-fb29-4493-bf9c-47b8dbbed442?#《HTTP/2》
博文内容来自于《HTTP2 基础教程》
HTTP 协议名称为超文本传输协议,字面意思可以看出 HTTP 诞生之初其实是为了传输超文本,也就是 HTML(超文本标记语言)。但是随着各种技术的发展,网络世界中需要传输的内部不再局限于超文本,于是就迎来了 HTTP1.1,也就是现在主要使用的 HTTP 协议。
详情可以参考这篇博客:https://www.cnblogs.com/keva/p/spdy-protocol.html
HTTP2/2 诞生之前,Google 提出了一种 HTTP 的替代方案:SPDY。
在 SPDY 之前,人们认为在商业应用中没有必要对 HTTP/1.1 做出突破性的,不兼容的改变。要兼容浏览器,服务器,网络代理和其他各种各样的中间件,代价极其昂贵(比如我们这一代人讲了 20 多年的中国话,突然有一天要把日常用语转换为其他的语言,这个转换成本是要经过一代人的努力的)。
SPDY 协议在性能上对 HTTP 做了优化,核心是尽量减少连接个数。于是 SPDY 奠定了 HTTP/2 的基础,例如多路复用,帧和首部压缩等。
由于【2.1 HTTP/1.1 缺点】内标注的一些问题,HTTP 工作组在启动下一个 HTTP 版本的工作的时候,纲领的关键部分阐述了工作组对新协议的期望(也就是我们日常项目中的需求文档):
方法、状态码、∪RI 和首部字段
从我的经验来看,想快速了解协议的话,直接看协议的报文结构是最快的。因为协议的一些特性都在报文上体现,而代码/调试工具只是来模拟报文进行发送/响应。
HTTP/1.1 报文
HTTP/2 报文
报文具体内容可以搜下:HTTP/2 帧结构/-
HTTP/2 的报文被称为:分帧层。更改了数据传输类型,放弃了庞大的数据包,改用数据帧来传输数据。因此,HTTP/2 是一个二进制协议,方便了机器解析,但是肉眼看起来比较困难
分帧层大致可以分为两部分:headers 和 data。不管怎么设计,目的都是传输 HTTP,而不是其他内容。
报文结构如下所示:
HTTP/2 规范对流的定义是:HTTP/2 连接上独立的,双向的帧序列和交换。
流,是连接上的一系列帧的统称,或者可以叫做会话流。
如果客户端想要发出请求,就会开启一个新的流(发送 headers 帧。
然后,服务器将在这个流上回复。和 HTTP/1.1 的请求/响应流程区别在于有分帧,所以多个请求和响应可以交错,而不会互相阻塞。流 ID 用来表示帧所属的流。
HTTP/2 中,一切几乎都是对称的。
服务端和客户端都可以调整传输的速度。而在 HTTP/1.1 中,只要客户端可以处理,服务器就会尽可能快的发送数据。
当一端接收并消费被发送数据时,它将发出一个 WINDOW_UPDATE 帧来指示更新后的处理字节的能力。
首部压缩(HPACK)是 HTTP/2 的关键因素。HPACK 是一种表查找压缩方案,利用霍夫曼编码获得接近 GZIP 的压缩率。
大概指的是:
请求端和响应端各维护了两张表格。其中之一是动态表,一张是静态表,由最常见首部的键值组合而成。
服务器会查找对应的表格,并把这些数字还原成索引对应的完整首部。
从【3.1】的帧结构可知 HTTP/2 是一个二进制协议,所以需要了解一个对二进制友好的数据结构:protobuf。
目前基于 HTTP/2 的服务的话,主流的是 Grpc 框架,对应延伸出来的就是 grpc 调试工具。