上一篇文章前端阶段性总结(一):HTTP 协议,从 1.0 到 2.0 梳理了一下 HTTP 协议。本文将重点介绍,在前端通信协议中 HTTP2 的前身,具有开拓性意义的 SPDY,以及具有颠覆性的 QUIC 协议。
一、开拓者:SPDY
1. 简介:
spdy 是由 google 推行的,改进版本的 HTTP1.1(那时候还没有 HTTP2)。它基于 TCP 协议,在 HTTP 的基础上,结合 HTTP1.X 的多个痛点进行改进和升级的产物。它的出现使 web 的加载速度有极大的提高。HTTP2 也借鉴了很多 spdy 的特性。
2. 特性:
上一篇文章中有介绍,基本和 HTTP2 差不多,这里就不赘述了:
多路复用
头部压缩
服务器推送
请求优先级
spdy 的架构图:
3. 现状:
在 HTTP2 未推出之前,spdy 在业界内已经有一定的市场占用量,并且它的成绩也是不容忽视的,因此在很长一段时间,市场上可能会见到 spdy 和 h2 同时使用的场景。
二、颠覆者:QUIC
1. 前置知识:
TCP 与 UDP
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
1)提供 IP 环境下的数据可靠传输(一台计算机发出的字节流会无差错的发往网络上的其他计算机,而且计算机 A 接收数据包的时候,也会向计算机 B 回发数据包,这也会产生部分通信量),有效流控,全双工操作(数据在两个方向上能同时传递),多路复用服务,是面向连接,端到端的传输;
2)面向连接:正式通信前必须要与对方建立连接。事先为所发送的数据开辟出连接好的通道,然后再进行数据发送,像打电话。
3)TCP 支持的应用协议:Telnet(远程登录)、FTP(文件传输协议)、SMTP(简单邮件传输协议)。TCP 用于传输数据量大,可靠性要求高的应用。
UDP(User Datagram Protocol 用户数据报协议)是 OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
1) 面向非连接的 (正式通信前不必与对方建立连接,不管对方状态就直接发送,像短信,QQ),不能提供可靠性、流控、差错恢复功能。UDP 用于一次只传送少量数据,可靠性要求低、传输经济等应用。2) UDP 支持的应用协议:NFS(网络文件系统)、SNMP(简单网络管理系统)、DNS(主域名称系统)、TFTP(通用文件传输协议) 等。
总的来说:TCP:面向连接、传输可靠(保证数据正确性, 保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
Diffie-Hellman 算法
D- H 算法的数学基础是离散对数的数学难题,其加密过程如下:
(1)客户端与服务端确定两个大素数 n 和 g,这两个数不用保密
(2)客户端选择另一个大随机数 x,并计算 A 如下:A = g^x mod n
(3)客户端将 A 发给服务端
(4)服务端选择另一个大随机数 y,并计算 B 如下:B = g^y mod n
(5)服务端将 B 发给客户端
(7)计算秘密密钥 K1 如下:K1=B^2 mod n,计算秘密密钥 K2 如下:K2=A^y mod n , K1=K2,因此服务端和客户端可以用其进行加解密
攻击者知道 n 和 g,并且截获了 A 和 B,但是当它们都是非常大的数的时候,依靠这四个数来计算 k1 和 k2 非常困难,这就是离散对数数学难题。
2. 什么是 QUIC?
quic 是 google 推出的,基于 UDP 的高效可靠协议。quic 在 UDP 的基础上实现了 TCP 的一些特性,而由于底层使用的是 UDP,所以传输效率比 TCP 高效。
3. 特性
a. 基于 UDP 建立的连接:
我们知道,基于 TCP 的协议,如 http2,在首次建立连接的时候需要进行三次握手,即至少需要 3 个 ntt,而考虑安全 HTTPS 的 TLS 层,又需要至少次的通信才能协商出密钥。这在短连接的场景中极大的增加了网络延迟,而这种延迟是无法避免的。而基于 UDP 的 quic 协议,则不需要 3 次握手的过程,甚至在安全协商阶段只需要进行 1~2 次的协商通信,即可建立安全稳定的连接,极大的减少了网络延迟。
b. 基于 Diffie-Hellman 的加密算法:
HTTPS 使用的是 TLS + SSL 的加密手段,在交换证书、协商密钥的过程中,至少需要 2 次 ntt 进行协商通信。而 quic 使用了 Diffie-Hellman 算法, 算法的原理使得客户端和浏览器之间只需要 1 次的协商就能获得通信密钥,quic 建立安全链接的详细过程:
客户端发起 Inchoate client hello
服务器返回 Rejection,包括密钥交换算法的公钥信息,算法信息,证书信息等被放到 server config 中传给客户端
客户端发起 client hello,包括客户端公钥信息
后续发起连接的过程中,一旦客户端缓存或持久化了 server config,就可以复用并结合本地生成的私钥进行加密数据传输了,不需要再次握手,从而实现 0RTT 建立连接。
c. 改进的多路复用
我们知道,无论是 HTTP2 还是 SPDY, 基于 TCP 的协议尽管实现了多路复用,但仍然没有避免队头阻塞的问题,这个问题是由于 TCP 底层的实现造成的,即 TCP 的包有严格的顺序控制,前序包如果丢失,则后续包即使返回了也不会通知到应用层协议,从而导致了前序包阻塞。而 quic 基于 UDP 则天然的避免了这个问题,由于 UDP 没有严格的包顺序,一个包的阻塞只会影响它自身,并不会影响到其他资源,且 quic 也实现了类似 HTTP2 的多路复用,这种没有队头阻塞的多路复用对延迟的降低是显而易见的。
d. 连接的迁移
在以往的基于 TCP 的协议中,往往使用四元组(源 IP,源端口,目的 IP,目的端口)来标识一条连接,当四元组中的 IP 或端口任一个发生变化了连接就需要重新建立,从而不具备连接迁移的能力。而 QUIC 使用了 connection id 对连接进行唯一标识。即使网络从 4G 变成了 wifi,只要两次连接中的 connection id 不变,并且客户端或者服务器能通过校验,就不需要重新建立连接,连接迁移就能成功。这在移动端场景的优势极为明显,因为手机经常会在 wifi 和 4g 中切换,使用 quic 协议降低了重建连接的成本。
e. 协商的升级
在 chorme 浏览器中,发起一个 TCP 请求,这个请求会同时与服务器开始建立 tcp 和 quic 的连接(前提是服务器支持),如果 quic 连接先建立成功,则使用 quic 建立的连接通信,反之,则使用 tcp 建立的连接进行通信。具体步骤如下:
1、客户端发出 tcp 请求
2、服务端如果支持 quic 可以通过响应头 alt-svc 告知客户端
3、客户端同时发起 tcp 连接和 quic 连接竞赛
4、一旦 quic 建立连接获胜则采用 quic 协议发送请求
5、如遇网络或服务器不支持 quic/udp,客户端标记 quic 为 broken
6、传输中的请求通过 tcp 重发
7、5min 后尝试重试 quic,下一次尝试增大到 10min
8、一旦再次成功采用 quic 并把 broken 标记取消
其中,支持 quic 的 alt-svc 头部信息如下图示:
d. 其他特性:
改进的拥塞控制
丢包恢复
底层的连接持久化
head stream 保证包顺序
双级别流量控制
三、总结与思考
在 web 通信协议的演进中,SPDY 是不可或缺的角色,在没有 HTTP2 的时代,它的出现极大的提升了网页加载速度,甚至 HTTP2 也是吸取了它很多的特性而制定的,是当之无愧的开拓者。而在有 HTTP2 的今天,quic 协议的出现无异于对 TCP 的颠覆,它在底层抛弃了传统的 TCP,而使用高效的 UDP,并实现了 TCP 的特性,并且没有修改到应用层协议,我们可以无缝的基于原有的规范去开发。最后,这两东西居然都是 google 提出并推行的。只能说 google 真的牛叉~
参考文章 https://www.jianshu.com/p/2d8…https://wetest.qq.com/lab/vie…https://cloud.tencent.com/dev…https://www.zhihu.com/questio…