HTTP2
一:概述
HTTP通过SSL/TLS在安全上达到了极致,但是在性能方面只优化了握手加密的环节,整体的数据传输也只能依靠"落后"的长连接技术,所以HTTP2对HTTP的性能进行改进。由于以前以小版本号命名HTTP1.0和HTTP1.1的时候,人们难以区分差别,造成了许多的混乱和误解,所以现在HTTP使用大版本号。
二:HTTP/2特性
2.1 兼容HTTP/1
HTTP/2把HTTP/1的分解为了语法和语义两部分。
语义部分:
与HTTP/1一致,例如请求方法、URI、状态码、头字段等概念都保留不变,这样基于HTTP协议的上层应用也不需要做任何修改,完美的衔接HTTP/2。HTTP2没有引入新的协议名,仍然以http表示明文协议,以https表示加密协议。
语法部分:
1.头部压缩:由于报文Header会携带大量的固定头字段,在成千上万的请求响应报文里有很多重复的字段值,让大量带宽消耗在这些冗余的数据上。HTTP2开发了专门的"HPACK",在客户端和服务器两端建立"字典",用索引号表示重复的字符串,采用哈夫曼编码来压缩整数和字符串。
2.二进制格式:HTTP/2将不再使用ASCII码,而是向下层的TCP/IP协议靠近,全面采用二进制格式。因为在使用纯文本的格式时容易产生多义性,比如大小写、空白字符、回车换行、多字少字等,程序处理时复杂,效率低,而采用二进制格式解析起来没歧义,简单高效而且体积小。HTTP/2将原来的 Header+body 的消息变为了数个小片的二进制帧,用HEADERS帧存放头数据,DATA帧存放实体数据。
3.虚拟的流:HTTP/2定义了流的概念,它是二进制帧的双向传输序列,同一个信息往返的帧会分配一个唯一的流ID,里面流动的是一串有先后顺序的帧数据,这些数据帧按照次序组装起来就是HTTP/1中的请求报文和响应报文。HTTP/2在TCP连接上用流同时发送多个碎片化信息,也就是多路复用,解决了队头阻塞的问题,降低了延迟,大幅度提高了连接的利用率。HTTP/2还添加了一些控制帧来管理虚拟的流,实现了优先级和流量控制。而且服务器不再是被动地响应请求,也可以通过新建流主动向客户端发送信息。
4.强化安全:HTTP2定义了两个字符串标识符"h2":表示加密的HTTP/2,"h2c":表示明文的HTTP/2。底层通信协议要求采用TLS1.2以上版本。
HTTP/2协议栈

HTTP/2内部剖析
连接前言
由于HTTP/2是基于TLS协议的,所以在正式收发数据之前,要进行TCP握手和TLS握手,在TLS握手成功之后,客户端必须要发送一个连接前言,用来确认建立HTTP/2连接。连接前言是标准的HTTP/1.0请求报文,使用纯文本的ASCII码格式,请求方法是关键字PRI。
头部压缩
在请求发送之前,必须要用HPACK算法来压缩头部数据,HPACK算法是专门为压缩HTTP头部定制的算法,是有状态的算法,需要客户端和服务端格子维护一份索引表,压缩和解压就是查表和更新表的操作。HTTP/2废除了原有的起始行概念,将起始行里面的请求方法、URI、状态码等统一转换成了头字段的形式,叫做伪头字段,格式是会在字段名前加一个":",比如
:authority: search.bilibili.com #域名
:method: GET #请求方法
:scheme: https #协议
现在报文头就全是"Key-Value"形式的字段,HTTP/2为一些常用的头字段定义了一个只读的静态表,查表就可以知道字段名和对应的值。
二进制帧
二进制帧结构

帧类型可以分为数据帧和控制帧两类,HEADERS帧和DATA帧属于数据帧,用于存放HTTP报文,而SETTINGS、PING、PRIORITY是用来管理流的控制帧。
帧标志用于携带简单的控制信息。
流标识符用于从乱序的帧里面识别出具有相同流ID的帧序列。

浙公网安备 33010602011771号