目录
HTTP3
请求实现基本流程: DNS解析(域名转换为ip地址)、TCP三次握手(服务端确认)、TLS四次握手(传输通道的数据加密,目的是让通信双方能够获得解析信息的以“钥匙”“)、用户数据传输。
TLS
TLS(传输安全性)协议用于网络通信中提供安全性,握手的目的是确保通信双方可以安全的交换数据。主要通过四次信息交换,客户端Hello、服务器Hello(ServerHello)、客户端密钥交换(Client Key Exchange)、完成(Finished)。
TLS四次握手过程通过安全的密钥交换和验证,确保客户端和服务器之间的通信是加密的、完整的,避免中间人攻击、重放攻击等常见安全威胁。通过这种方式,双方可以在不直接传输密钥的情况下,共同生成一个安全的会话密钥,用于保护后续的数据传输。
QUIC
HTTP3的核心是QUIC协议。QUIC协议即是只保留最后用户请求响应部分,将前面TCP三次握手和TCP四次握手抛弃掉。
QUIC基于UDP工作流程分析,首先客户端发送一个包含ClientHello和应用数据的UDP包,然后客户端回应ServerHello和加密参数以及应用数据的UDP包,客户端和服务器完成TLS握手协商出回话秘钥,双方基于该秘钥进行数据传输。最后QUIC通过连接ID管理,可以在网络路径发生变化的时候保持连接不中断。
QUIC协议根据UDP实现,UDP上进行了流量控制、拥塞控制以及多路复用等以保证传输通道的可靠性。QUIC的目的是提供低延迟、高可靠性的网络传输。
- 多路复用连接:允许单个UDP连接上多路复用多个逻辑连接,避免了TCP多连接所带来的延迟和资源开销。QUIC通过连接ID区分不同的逻辑连接。
- 0-RTT和1-RTT连接建立:QUIC支持快速连接建立,客户端可以在第一个数据包中就发送应用数据(0-RTT),从而减少初次连接的延迟。此外,通过一次往返(1-RTT),客户端和服务器可以建立加密的连接。例如客户端发送一个包含握手数据和应用数据初始化的UDP数据包,服务器可以立马响应。
- 内置加密:内置了TLS加密协议,所有数据包都经过加密处理,确保传输安全和隐私性。
- 拥塞控制和流量控制:QUIC实现了类似于TCP的拥塞控制机制,同时通过流量控制防止发送方过度发送数据资源,从而确保网络的稳定性和公平性。QUIC使用流ID和控制窗口来管理数据流量,同事根据网络状况动态调整发送速率。
- 包重传和乱码处理:QUIC数据包包含一个连续递增包序号,接收方可以基于包序号检测丢失的包并重传。
HTTP3和QUIC关系的理解:QUIC实现在用户态,但是仍任务QUIC其是传输层的协议(因为其主要功能仍然是传输数据),而http3是应用层的协议。HTTP3的核心是QUIC协议。HTTP3是对TCP传输协议的升级,而不是彻底的颠覆。
0-RTT握手
0-RTT表示不消耗时间就可以握手成功建立连接。但是首次连接之前需要进行一次RTT握手。通过握手的时候携带了http数据。类似于两人第一次见面时已经商量好暗号发送信息,后续的信息发送只要加上该暗号就可以发送专属于两者的加密信息。
连接迁移
连接迁移解决的目标问题:当频繁切换网络环境的时候,会导致网络环境拥塞,用户体验上会有延迟卡顿现象。
TCP情况下不支持连接迁移的原因,因为其是利用ip和端口号的标识唯一主机,切换网络的时候ip地址会发生变化,此时则需要重新建立连接。quic则是通过给每一条连接发送一个唯一ID,无论ip地址和端口号如何变化,只要ID没变就认为这是同一条连接。
接入层架构分析
客户端到达服务端之间,经过两个负载均衡器,四层负载均衡器(网络负载均衡)和七层负载均衡器(安全网关)
四层负载均衡器和七层负载均衡器知识补充
连接迁移产生的问题
ip地址发生变化时,经过四层负载均衡器时,会将数据包发送到不同的服务器上。
七层负载均衡器会受多核影响,可能会导致连接迁移前后数据包发送给了不同进程。
四层负载均衡器修改四元组一致性哈希,同时增加逻辑判断,判断是否为quic报文。
七层负载均衡器在内核中,通过连接ID确定对应的信息传输进程
拥塞控制算法
QUIC:流的多路复用
QUIC中数据包的序号是严格按照单调递增。 TCP传输数据包的时候,因为延时或者丢包的原因,会导致服务端收到同样序号的数据包,从而导致TCP重传包的二义性。重传包的二义性又导致了RTT的计算不准确,最终导致拥塞控制算法的不准确。
两级流量控制
TCP的滑动窗口会受到数据包丢失影响,因为TCP下如果出现数据包丢失就不可以继续发送数据。QUIC的可用窗口则不受该影响。
协议竟速
为解决不支持UDP协议的场景,请求连接的时候,同时请求quic和TCP两个连接,哪个连接成功就用哪一个。
http3的应用场景
- 移动网络
- 快速恢复:网络切换时可以实现快速恢复连接,不需要像TCP重新建立连接
- 低延迟:减少建立的往返时间
- 高延迟网络
- 0-RTT握手:第一个数据包中就包含数据,有效减少延迟
- 减少重传开销:QUIC的快速重传和错误恢复机制能够减少由于丢包带来的延迟
- 视频通信和实时通信
- 多路复用:避免了TCP队头阻塞的问题,提高传输效率和用户体验
- 流量控制:更好的使用实时流媒体的需求,减少缓冲和卡顿现象
- web应用
- 快速加载时间:减少延迟和提升多路复用效率
- 增强客户体验:例如在游戏上可以提高用户的体验感
HTTP版本
HTTP1.1
keepalive达到长连接的目的,避免重复建立连接。
在 HTTP/1.0 中,每个请求/响应对需要单独的 TCP 连接,即一个请求完成后,连接就会关闭。这种做法存在较大的开销,因为每次都需要重新建立和关闭连接,增加了延迟和资源消耗。
HTTP/1.1 引入了 Keep-Alive 头部,允许在同一个 TCP 连接上复用多个请求和响应,直到客户端或服务器主动关闭连接。这减少了连接建立和关闭的次数,从而提高了传输效率。
Pipeline:在同一个持久连接上,客户端可以在收到前一个响应之前发送的多个请求。从而提高网络效率和性能,减少延迟。
HTTP1.1管道的限制
- 中间设备的兼容性:许多中间设备(如代理服务器、负载均衡器等)不完全支持HTTP管道化,可能导致请求被阻塞或丢弃。
- 队头阻塞:如果前面的请求处理时间较长,后续请求的响应会被阻塞,导致性能下降。
- 浏览器和服务器实现:并非所有浏览器和服务器都完全支持管道化,有些实现可能存在兼容性问题
HTTP/2 HTTP/3的改进
- HTTP/2:引入二进制分帧层,使得多个请求和响应可以在一个连接上并行传输,避免了队头阻塞问题。
- HTTP/3:基于QUIC协议,进一步改进了连接管理和传输性能,同样支持多路复用,且更加高效和可靠。
HTTP2
二进制帧
请求的所有信息都是按照二进制形式发送,而不是按照字符串的形式进行发送。
流
数据包发送拥有多条通道,实现分片交叉发送,而不是顺序发送。
流可以简单的理解成一个请求,将所有的请求混合在一起,同时在TCP连接上进行传输,区分数据包则是使用ID进行区分。
流优先级和流依赖,可能会导致网络传输数据的速度不如旧版本。流的优先级,应用层给发送的资源设定优先级,根据优先级的大小发送数据流,所以会导致部分数据接收速度慢。流依赖,数据流有一定的的顺序,例如只有拿到1号数据后才可以拿到2号数据。
队头阻塞
TCP传输协议要求报文必须按照一定的顺序进行排列,但是发送的时候不是按照顺序进行发送,所以导致了部分数据不到位则没有办法进行处理。
TCP队头阻塞:TCP是面向连接的可靠传输协议,保证数据包按序到达。也就是接收端必须按照发送端的顺序接收数据包。如果出现一个数据包在传输过程中丢失或者延迟,即使后续的数据包已经到达,接收端也无法处理这些数据包,直到丢失或者延迟的数据包被成功重传并接收。
原理分析
- 数据包传输:TCP将数据分割成多个小数据包并赋予序列号进行传输;接收端通过序列号来重组数据包,确保数据的完整性和顺序。
- 数据包丢失或者延迟:传输过程中如果出现数据包丢失或延迟的情况,接收端会等待该数据包的到来,即使此时后续数据包已经达到,由于需要按序进行处理,接收端无法处理这些数据包。
- 重传机制:重传计时器到达时间后会重新发送数据包,接收端此时接收到重传的数据包后才开始处理后续的数据包。
队头阻塞的影响
- 延迟增加:由于必须等待丢失或延迟的数据包,导致整个传输过程的延迟增加。
- 吞吐量降低:在网络不稳定或高丢包率环境中,频繁的重传会降低有效数据的传输率。
- 资源浪费:发送端和接收端需要额外的资源(如缓存、处理能力)来管理和重传丢失的数据包。
队头阻塞解决方法
1. HTTP/2 多路复用
HTTP/2 通过多路复用允许在同一个 TCP 连接上并行发送多个请求和响应,解决了应用层的 HOL 阻塞问题。即使一个流(Stream)中的数据被阻塞,其他流中的数据仍然可以被处理。
2. HTTP/3 QUIC 协议
HTTP/3 基于 QUIC 协议,使用 UDP 作为传输层。QUIC 实现了独立的数据流,每个流都有自己的序列号和重传机制,即使一个流的数据被阻塞,也不会影响其他流的数据传输。
3. 分片重传
一些高级传输协议通过分片重传机制,将丢失的数据包分成更小的片段进行重传,减少重传的开销和延迟
//队头阻塞,2号包丢失
发送端 接收端
Packet 1 --> Packet 1
Packet 2 --> [丢失]
Packet 3 --> [等待 Packet 2]
重传 Packet 2 --> Packet 2
Packet 3 --> Packet 3
//正常传输
发送端 接收端
Packet 1 --> Packet 1
Packet 2 --> Packet 2
Packet 3 --> Packet 3