参考链接:面试官:说说 HTTP1.0/1.1/2.0 的区别? (opens new window)
# HTTP1.0
HTTP协议的第二个版本,第一个在通讯中指定版本号的HTTP协议版本。
- 版本信息现在会随着每个请求发送(HTTP1.0被追加到GET行)。
- 状态代码行也会在响应开始时发送,允许浏览器本身了解请求的成功或失败,并相应地调整其行为(如以特定方式更新或使用本地缓存)。
- 引入了HTTP头的概念,无论是对于请求还是响应,允许传输元数据,并使协议非常灵活和可扩展。
Content-Type标头告诉客户端实际返回的内容的内容类型。在Content-Type标头帮助下,增加了传输除纯文本HTML文件外的其他类型文档的能力。- HTTP1.0浏览器与服务器只保持短暂的连接,每次请求都需要与服务器建立一个TCP连接,如果需要建立长连接,需要设置一个非标准的Connection字段
Connection: keep-alive。
# HTTP1.1
HTTP1.0的多种不同的实现运用起来有些混乱,HTTP1.1是第一个标准化版本。
- 默认支持长连接(
Connection: keep-alive),节省了多次打开它的时间,以显示嵌入到单个原始文档中的资源。 - 增加流水线操作,允许在第一个应答被完全发送之前发送第二个请求,以降低通信的延迟,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。
- 支持响应分块。
- 引入Range (opens new window),允许只请求资源某个部分。
- 引入额外的缓存控制机制,如
If-Modified-Since、If-Unmodified-Since、If-Match、If-None-Match等。 - 引入内容协商,包括语言,编码,或类型,并允许客户端和服务器约定以最适当的内容进行交换。
- 通过Host头,能够使不同的域名配置在同一个IP地址的服务器。
- 安全性得到了提高。
- 添加了其他的请求方法:
put、delete、options等。
# HTTP2
HTTP2在相比之前版本,性能上有很大的提升:
- 二进制分帧。
- 首部压缩。
- 多路复用。
- 服务器推送。
# 二进制分帧
帧是HTTP2通信中最小单位信息。HTTP2采用二进制格式传输数据,而非HTTP1.x的文本格式,解析起来更高效。将请求和响应数据分割为更小的帧,并且它们采用二进制编码。HTTP2中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装,这也是多路复用同时发送数据的实现条件。
# 首部压缩
HTTP2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。首部表在HTTP2的连接存续期内始终存在,由客户端和服务器共同渐进地更新。例如两个请求,请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。
# 多路复用
HTTP2复用TCP连接,在一个连接里,客户端和浏览器都可以「同时」发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了“队头堵塞”。在HTTP1中,每次请求都会建立一次HTTP连接,也就是我们常说的3次握手4次挥手,这个过程在一次请求过程中占用了相当长的时间,即使开启了Keep-Alive,解决了多次连接的问题,但是依然有两个效率上的问题:
- 串行的文件传输。当请求a文件时,b文件只能等待,等待a连接到服务器、服务器处理文件、服务器返回文件,这三个步骤。我们假设这三步用时都是1秒,那么a文件用时为3秒,b文件传输完成用时为6秒,依此类推。(注:此项计算有一个前提条件,就是浏览器和服务器是单通道传输)。
- 连接数过多。我们假设Apache设置了最大并发数为300,因为浏览器限制,浏览器为了控制资源会有6-8个TCP连接的限制,服务器能承载的并发数有限,后面访问的就需要等待前面某个请求处理完成。
HTTP2的多路复用就是为了解决上述的两个性能问题。在HTTP2中,传输是基于二进制帧的,有两个非常重要的概念,分别是帧(frame)和流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。多路复用,就是在一个TCP连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免HTTP旧版本中的队头阻塞问题,极大的提高传输性能。
- 同域名下所有通信都在单个连接上完成,消除了因多个TCP连接而带来的延时和内存消耗。
- 单个连接上可以并行交错的请求和响应,之间互不干扰。
# 服务器推送
HTTP2引入服务器推送,允许服务端推送资源给客户端。服务器会顺便把一些客户端需要的资源一起推送到客户端,如在响应一个页面请求中,就可以随同页面的其它资源,免得客户端再次创建连接发送请求到服务器端获取,这种方式非常合适加载静态资源。
HTTP2的服务端推送和SSE的区别是什么?
- SSE:侧重实现服务端实时的将更新数据单向推送给客户端,例如股票行情、新闻推送、实时监控数据。
- HTTP2:服务端主动推送则是在优化资源获取效率场景下;服务端主动推送客户端后续可能需要的资源,像网页相关联的脚本、样式文件等,减少客户端请求的次数。
# HTTP3
# 基于QUIC协议
多路复用无队头阻塞
HTTP3基于QUIC(Quick UDP Internet Connections)协议,它继承了QUIC的多路复用特性。在HTTP2中,虽然也有多路复用,但由于底层使用TCP协议,可能会出现队头阻塞问题。而QUIC的多路复用在一个连接上可以同时处理多个独立的流,并且各个流之间不会相互影响,即使某个流出现丢包,也不会阻塞其他流的传输。
例如,当同时加载一个网页的多个资源时,如果其中一个资源的数据包丢失,在HTTP2中可能会导致整个连接的传输受阻,直到丢失的数据包被重传成功。而在HTTP3中,其他资源的传输不受影响,大大提高了传输效率。
快速连接建立
QUIC协议在连接建立方面比传统的TCP和TLS握手更快。它将TLS加密层整合到QUIC协议内部,减少了连接建立的往返次数。在首次连接时,虽然也需要一些时间进行密钥交换等操作,但后续连接可以利用之前的连接状态进行快速恢复,实现0-RTT(Round-Trip Time)或1-RTT的连接建立时间。
例如,在移动网络环境下,用户频繁切换网络或重新打开应用时,HTTP3可以更快地建立连接,减少用户等待时间,提供更流畅的体验。
# 改进的拥塞控制
可插拔的拥塞控制算法
HTTP3允许使用不同的拥塞控制算法,并且可以根据网络环境动态切换。这使得它能够更好地适应各种网络条件,如高延迟、高丢包率的网络环境。
例如,在无线网络环境下,可以选择更适合这种环境的拥塞控制算法,提高数据传输的效率和稳定性。
更精准的拥塞控制
QUIC协议的拥塞控制机制比TCP更加精细。它可以更好地感知网络的拥塞状态,及时调整发送速率,避免网络拥塞的发生。同时,它还可以对不同的流进行独立的拥塞控制,提高整体的网络利用率。
例如,当网络出现拥塞时,HTTP3可以更快地降低发送速率,避免拥塞进一步恶化。而在网络状况好转时,又能迅速提高发送速率,充分利用网络带宽。
# 增强的安全性
内置加密
QUIC协议在设计上就内置了加密功能,从一开始就对数据进行加密传输,提供了更好的安全性。这避免了像TCP那样在连接建立后再进行加密协商的过程,减少了安全风险。
例如,在网络中传输的数据更难被窃听或篡改,保护用户的隐私和数据安全。
前向安全
HTTP3继承了QUIC的前向安全特性。即使一个密钥被泄露,也不会影响之前的通信安全。这意味着攻击者无法通过破解当前的密钥来获取之前的通信内容。
例如,如果一个服务器的密钥在某个时间点被泄露,之前通过HTTP3传输的通信内容仍然是安全的,不会被攻击者窃取。