面试真经 HTTP HTTPS HTTP1.1 HTTP2 HTTP3

全栈码农画像

共 2854字,需浏览 6分钟

 ·

2021-03-04 07:58

金山银四, 是一个骚动的季节。

昨天在某大厂面试中,就被问到"你用过HTTPS没?" 这种直白的问题,回答的并不流畅,结合最近我在写gRPC, 索性梳理一下 HTTP HTTPS HTTP1.1 HTTP2 HTTP3

HTTP

客户端(如Web浏览器)从服务器(如Web服务器)请求资源时用到的协议。

HTTPS

一种加密HTTP的方式。一般使用SSL/TLS将HTTP消息包装为加密格式。
现代Web越来越趋向于使用HTTPS, 除非您有充足的理由拒绝HTTPS,否则现在创建的任何网站上都推荐使用HTTPS (传送门)

当通过未加密的HTTP为网站提供服务时,越来越多的Web浏览器会发出警告。

HTTP/1.1

这是HTTP协议目前的流行格式。它是基于文本的协议

HTTP/1.1消息可以是未加密的(网站地址以http://开头),也可以使用HTTPS加密(网站地址以https://开头)。客户端使用URL的开头来决定要使用的协议,如果未提供,通常默认为http://

HTTP2

2015年发布的HTTP新版本,通过从基于文本的协议转移到二进制协议,解决了1.1版本的性能问题。

对于客户端和服务器,这更容易解析,减少了错误的发生,并且还允许多路复用。

HTTP/2没有强制要求使用TLS,可以通过未加密(http://)和加密(https://)通道使用,但是Web浏览器仅通过HTTPS支持它(在此情况下,连接开始时进行的HTTPS协商决定了后面使用HTTP/1.1还是HTTP/2)

gRpc是谷歌开源的远程过程调用框架,基于HTTP2 协议研发。

HTTP3

HTTP的下一个版本,目前正在开发中。它可能会在2020年末甚至2021年完成,您可能会在2020年末甚至2021年末看到一些广泛应用。

它将建立在称为QUIC的基于UDP的传输之上(而不是HTTP/1.1和HTTP/2所基于的基于TCP的协议)。

它将在协议中包括HTTPS,因此HTTP/3仅可通过HTTPS使用。


HTTP/2到底有哪些具体变化?

二进制分帧

先来理解几个概念:

:HTTP/2数据通信的最小单位。
     消息:指 HTTP/2 中逻辑上的 HTTP 消息,例如请求和响应等,消息由一个或多个帧组成。

:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数ID。

HTTP/2采用二进制格式传输数据,而非HTTP1.x的文本格式,二进制协议解析起来更高效。

HTTP / 1 的请求和响应报文,都是由起始行、首部和实体正文(可选)组成,各部分之间以文本换行符分隔。
HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。

HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流
每个数据流都以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。

多路复用

多路复用,代替原来的序列和阻塞机制, 所有请求都是通过一个TCP连接并发完成。
HTTP 1.x 中,如果想并发多个请求,必须使用多个TCP连接,且浏览器为了控制资源,还会对单个域名有 6-8个的TCP连接请求限制,如下图,红色圈出来的请求就因域名链接数已超过限制,而被挂起等待了一段时间:

在 HTTP/2 中,有了二进制分帧之后,HTTP/2不再依赖 TCP连接去实现多流并行了,在 HTTP/2中:

同域名下所有通信都在单个连接上完成。单个连接可以承载任意数量的双向数据流。数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。

这一特性,使性能有了极大提升:

同个域名只需要占用一个 TCP 连接,消除了因多个 TCP 连接而带来的延时和内存消耗。单个连接上可以并行交错的请求和响应,之间互不干扰。在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

服务器推送

服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。
例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。

服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。

头部压缩

HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。

HTTP/2对消息头采用HPACK(专为http/2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。

HTTP每一次通信都会携带一组头部,用于描述这次通信的的资源、浏览器属性、cookie等,例如

为了减少这块的资源消耗并提升性能, HTTP/2对这些首部采取了压缩策略:

HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。

例如:下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。

我们来看一个实际的例子,下面是用WireShark抓取的访问google首页的包:

上图是是访问https://www.google.com/抓到的第一个请求的头部,可以看到头部的内容,总共占用了437 bytes,我们选中头部的cookie,可以看到cookie总共占用了118 bytes。接下来我们看看第二个请求的头部:

从上图可以看到,得益于头部压缩,第二个请求中cookie只占用了1个字节,我们来看看变化了的Accept字段:

由于Accept字段与请求一中的内容不同,需要发送给服务器,所以占用了29 bytes。

结语

HTTP/2的通过支持请求与响应的多路复用来减少延迟,通过压缩HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。

Ref

- https://zhuanlan.zhihu.com/p/26559480


浏览 47
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报