为何基于UDP实现的QUIC/HTTP3比TCP更快?
这个问题问到点子上了!很多人刚接触QUIC时都会有这个疑惑——既然UDP本身没ACK机制,QUIC还得自己实现超时重传,那为啥不直接用现成的TCP?其实核心原因就是TCP天生带了几个“拖后腿”的短板,而QUIC借着UDP的灵活性,把这些短板给补上了。
我给你掰扯几个关键原因:
彻底解决TCP的“队头阻塞”老大难问题
TCP是个严格的“字节流协议”,所有数据必须按顺序交付。要是中间某个数据包丢了,哪怕后面的包已经到了服务器/客户端,也得乖乖等着丢的那个包重传成功,才能继续处理后面的数据——这就导致整个连接都被卡住。比如你加载网页时,一张图片的数据包丢了,那网页上的文字、样式表哪怕已经传过来了,也得等着这张图的包重传,整个页面加载节奏直接被拖慢。
而QUIC是基于“独立流”设计的,每个请求(比如加载一张图、一个脚本)都是单独的流。一个流的数据包丢了,只会重传这个流的包,其他流的该处理就处理,完全不互相耽误。相当于你排队买奶茶,前面的人忘带钱回去取,你不用跟着死等,直接去另一个窗口下单,效率自然高得多。握手速度快到飞起,少走很多弯路
咱们平时用的HTTPS是TCP+TLS的组合:TCP要三次握手(3个往返时间RTT),TLS还要额外做加密握手(又1-2个RTT),第一次建立连接得花好几个来回才能开始传数据。
QUIC直接把TLS 1.3的握手逻辑和连接建立合并了,第一次连接最多2个RTT就能启动数据传输;如果是复用之前的连接,甚至能做到0RTT——也就是刚发起请求,就能直接传数据,比TCP+TLS的组合快了不止一星半点。重传机制更精准,不做无用功
你提到的超时重传,QUIC可不是照搬TCP那套死板逻辑。TCP的重传是绑定整个连接的,一旦出现丢包,拥堵控制算法会保守地降低发送速度,哪怕只是个别包丢了。QUIC的重传是针对单个流的,而且它的拥堵控制算法更灵活,还支持“选择性重传”——哪个包丢了就重传哪个,不用像TCP那样有时候会连带重传后面已经成功送达的包。比如你发了10个包,第5个丢了,QUIC直接重传第5个就行,TCP可能会从第5个开始全重传一遍,纯纯浪费带宽和时间。网络切换不中断,无缝续传不卡顿
TCP是靠“四元组”(源IP、源端口、目的IP、目的端口)识别连接的,要是你从WiFi切到4G,IP地址变了,TCP连接直接断开,得重新握手、重新传数据。QUIC是用“连接ID”来标识连接的,不管你怎么换网络,只要连接ID不变,就能接着用原来的连接,不用重新建立连接——这在移动设备上体验提升特别明显,刷网页时切网络,不会突然卡住半天加载不出来。
简单说,QUIC不是抛弃了TCP的可靠机制,而是把这些机制从“整个连接绑定”改成了“每个流独立管理”,再加上UDP没有TCP那些历史包袱,自然能把传输速度提上去。
备注:内容来源于stack exchange,提问作者Qwark

