http这些知识你都知道嘛?

135 阅读9分钟

内容

这里讲解 http1.0、http1.1、http2.0它们的进化。还有 https 是如何加密验证的原理。

http

http1.0

从图中可以看出http1.0 都需要 tcp的慢启动、3次握手和四次挥手,这个就浪费了很多时间。 所以后续就出现http1.1 来解决这个问题(每次启动握手和挥手)。

http1.1

所以http1.1 就增加了一个长连接,用来多个请求可以使用同一个 tcp,减少握手和挥手的时间。有个知识,每个域名浏览器可以使用的tcp 连接数量是有规定的,谷歌浏览器是6个。

这个也有一个缺点: 第一个请求,要服务器响应到才能请求第二个。

所以http1.1 有进行优化,使用了一个叫做 pipeline(简单看下,一般没有网站在使用)

发送的时候并发发送,但是服务器先到先返回, 产生问题(请求有依赖关系, 第二个请求需要第一个请求先反应,但是这里无法保证谁先到)。还是会有阻塞。而且它还有限制只能是幂等请求(get、head等)才能应用,条件很苛刻基本没有使用的

现在http1.1 也暴露出问题: 每个请求需要通道中上一个响应收到才可以请求下一个,所以上一个请求慢就会堵塞住当前接口,因此 http/2 的多路复用就登场了。

http1.0 和 http1.1 的区别

缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略

长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

http2.0

两者的对比:

http2 有个知识通信都是在一个 tcp 连接上面完成的。 然后每个请求都是有分割的,分成一个个的数据帧形式。 看下图:

每个数据帧都是有一个序号的,所以我们就不用再等到上一个请求发送完然后响应到再请求

首先客户端按顺序发送,服务端按顺序接收。然后组装起来。

例如:请求一个js文件和一个css,假如它们的大小相同。用四个数来表示它们,1是js文件,2是css文件。http1.1: 11112222 如何请求。 http2.0: 11221122(不一定也可以12112212)交叉。疑问这样会更快嘛?如果加上浏览器的解析,当js先请求到就开始解析,然后解析时间再请求css文件。 如果多路复用就需要两个文件都请求到然后才能进行解析。

上面讲了http1.1 有一个 pipeline 的依赖关系的缺点。http2 是可以设置请求的优先级的。

http2.0 也有问题,当一个数据流分成了多个帧,当一个数据包丢失,因此就会 tcp 队头堵塞。后面会详细讲解。

http2.0对http 1.1 的优势

1.http2.0传输使用二进制格式(就是上面的帧)。http1.1 是文本格式。

  1. 多路复用。就是上面讲的。
  2. 服务端推送。例如: 当我们首次请求html 文件的时候。html 文件中有引入 js文件和css文件。当我们请求到 html 文件解析后也是需要再次请求那些js、 css文件的。因此服务器会帮我们也推送给客户端。就是前面的 type 帧的标示 PUSH_PROMISE, 告诉浏览器我要推送文件过来,浏览器等着接收就行。
  3. 头部压缩。 因为请求的数据中头部数据很多都是保持不变的。然后头部又包含了大量的信息例如 Cookie。所以需要减少体积。
  4. http2 必须使用 TSL 就是变成 https。这是因为目前主流浏览器的要求。所以就必须加上。

http2.0 的缺点是什么?

前面说了 http1.1 的堵塞,其实这个叫做 http 堵塞。还有一种堵塞是 tcp 对头堵塞。后面的 http3.0就是来解决这个问题。

http 堵塞

这里再回顾下前面 http1.1 的 http 堵塞。是因为服务器是按顺序接收的,所以我们不能两个接口一起请求,如两个接口数据都来,服务器会认为这些数据是一起的数据就混乱了,因此就出现 http2.0 用数据帧的形式,每个帧都有标示,告诉服务器我这个数据是哪个接口的。服务器就知道如何组装起来了。

tcp 堵塞

前面说到 http2.0 其实就是一个 tcp 连接(我看很多都是这样说的)。以下面例子说明:

image.png 这图是这位大佬关于队头阻塞(Head-of-Line blocking),看这一篇就足够了 十分推荐大家看下

就像前面说的 我们把数据切成帧的形式, 每个数据流可以包含不同数据流的帧。例如包3 就含有 流1和流2

tcp 是不知道自己在传输什么,当包2丢失了,它只知道包2需要重新发送,把包3缓存起来。但是这中间就有数据流1 其实是不应该别堵塞的,但是奈何因为数据流最后的数据在包3中,因此就也需要等待。这个时候就出现了 http3.0 QUIC 来解决这个堵塞问题。

小知识: http1.1 有6条 tcp的连接,因此可以很大的缓解tcp对头堵塞问题,以及对于先请求到的数据浏览器可以更快解析所以就有多路复用真的比http1.1 快嘛?

其实http2.0 又不止一个多路复用的优点。还有服务器端推送、头部压缩等

大家可以看那大佬的文章,他有非常详细的解答 队头堵塞,以及一些总结的思考()。

http 3.0

http3.0 的 QUIC 使用的协议是 UDP 协议。

为什么使用 udp 呢?

  • 基于TCP开发的设备和协议非常多,兼容困难
  • TCP协议栈是Linux内部的重要部分,修改和升级成本很大
  • UDP本身是无连接的、没有建链和拆链成本
  • UDP的数据包无队头阻塞问题
  • UDP改造成本小

image.png

QUIC 是如何解决对头堵塞问题?

再次使用大佬的图片:

image.png

这里就是把 DATA 流的id 单独抽离了出来,简单理解就是 QUIC 知道哪些数据不应该被堵塞要放行,就像包3 的流1 就把它放行了,流2的帧还是要被缓存起来等待包2的重新上传。

https

大家都知道 https 是十分的安全。但是不清楚为什么它很安全,安全的原理是什么。 下面就是讲解对称加密和非对称加密。简单理解对称加密(相同一把钥匙),非对称加密(不同两把钥匙)

对称加密

上面说了加密算钥匙,客户端和服务端都是要相同的钥匙,这里就出现了问题,钥匙是谁复制给谁的呢。

服务端告诉客户端,再传输过程中被黑客所拿到。

客户端告诉服务端,也不现实还是会被拿到。

客户端和服务器都存储。不现实,网站那么多客户端不可能记住所以服务器的钥匙。

所以对称加密失败,不是很安全

非对称加密

这里就是两把不同的钥匙。 服务器箱子(公钥) FG, 私钥 FS。 客户端箱子(公钥) KG, 私钥 KS(它们的缩写)

私钥S是来破解公钥G的锁起的箱子。

服务器把公钥给客户端: 服务器把箱子 FG 告诉浏览器。 这里可以被黑客获取,如下图。 HG(黑客公钥)、HS(黑客私钥)

https.drawio.png

假如客户端有公钥私钥,服务端没有。这样也不现实还是和前面一样。

但是服务器有公钥私钥,客户端也有公钥私钥。

客户端先把KG 告诉服务端,服务端用KG 分装自己的 FG 给客户端。 客户端拿到用私钥 KS 解开 KG 分装的箱子拿到 FG箱子。然后开始使用 FG箱子分装自己的数据给服务器。 然后服务器使用自己的 FS 钥匙打开 FG的箱子拿到数据,返回数据使用 KG 箱子包裹再传送给客户端。 当然客户端就使用 KS 来解开自己的 KG 箱子。就这样传输数据。

但是当中间人有公钥私钥也是可以做到劫持数据的。而且两组的公钥私钥十分的消耗性能,也是不推荐的。

所以非对称加密也是不安全的

非对称加密 + 对称加密

前面说到中间人也有公钥私钥,问题在于客户端不知道给它公钥箱子的人是谁。因此有一个第三方告诉客户端,这个公钥是服务器的。

数字证书

服务器向CA机构获取数字证书。

证书包含信息:

  • 颁发机构信息
  • 公钥
  • 公司信息
  • 域名
  • 有效期
  • hash算法
  • 数字签名

数字签名

为了证明这个证书没有被中间人串改改成自己的公钥。

所以 CA 机构根据服务器的基础信息经过 hash 产生了一个数据 S,再经过 CA 机构的公钥包裹形成了一个数字签名。

证书校验

客户端拿到证书对数字签名进行解密拿到数据 S, 然后根据证书上面的hash 算法再把证书服务器的基础信息进行hash 得到 T。 只要 T==S 就表示证书的正确的。公钥就是服务器的。

如何解开发CA机构的箱子呢,CA机构的箱子钥匙已经保存在了客户端中。

后面双方使用客户端产生对称加密(想象就是箱子和钥匙) 经过给的公钥包裹给服务器,服务器要自己的私钥解开拿到对称加密(箱子和钥匙)。后续通信就使用对称加密了。

image.png

总结

这篇文章是我看了下面的参考文章总结出来的,有些地方写的不是特别的清楚,大家可以点下面的链接做个全面的学习,很多知识点不可能从一篇文章中获得,需要阅读多篇文章,会加深你对这块知识的印象。

参考文章

HTTP1.0、HTTP1.1 和 HTTP2.0 的区别

关于队头阻塞(Head-of-Line blocking),看这一篇就足够了

图解|为什么HTTP3.0使用UDP协议

彻底搞懂HTTPS的加密原理

你连 HTTPS 原理都不懂,还讲“中间人攻击”?