近日,IETF宣称 HTTP/3 正式被标准化为 RFC 9114,QUIC 作为承载协议。写一段文字,我说的肯定是别人不聊的趣事。
QUIC Packet Header 的 Packet Number 字段使 QUIC “对每次传输的数据包确认,而不是对字节流确认”。
QUIC 多 Frame 复用一个 Packet 使承载 HTTP 的效率更高。
QUIC 支持 0-RTT 快速建连,但要维护 session。
QUIC 实现在用户态,支持快速迭代升级,但也更容易作恶,比如写一个不计成本的抢占式拥塞控制算法。
QUIC 内置安全…
…
我比较关注 QUIC 终于解决了 TCP 饱受诟病的两个问题:
- 无法区分原始报文和重传报文,导致RTT测量不准。
- 滑动窗口由于接收端序列号空洞而憋死,队头阻塞。
QUIC 真正映射了 IP 分组交换语义,字节流封装在 Packet 中,字节流和 Packet 分别被处理,端到端识别字节流,而传输只关注 Packet,流量控制和拥塞控制可更加精细:
- 流量控制:QUIC 针对配额进行流控,字节流空洞不再轻易憋死窗口。
- 拥塞控制:QUIC 针对 Packet 的标量特征采样而不必关心连续字节流。
QUIC 在传输层面关注 Packet 而不关注字节流,而此前 TCP 则将字节流和 Packet 综合考虑,以至于 TCP 实际上没有 Packet ,只有字节流,端到端和网络必不能兼顾。
所有这一切得益于 QUIC 复杂的协议头,复杂的协议头增强了表达能力,当然可以做更多事。
若将 QUIC 看作 TCP 的优化,回顾 TCP,我们发现 TCP 一直致力于所有这些方面的优化:
- 增加 SACK 可更精确判断丢包,重传效率更高。
- 增加了拥塞控制,直到更高效的 CUBIC/BBR 。
- 增加时间戳选项使 RTT 测量更精确。
- RACK 试图将传输时间序和字节序分开。
- FastOpen 试图缩短建连时间。
- …
但 TCP 受限的协议头终究让这些止于半途。终于重新设计的 QUIC 以更强的报头表达能力解决了 TCP 的问题。
因此将 QUIC 看作 TCP 的优化很有道理,QUIC 提供的承诺和 TCP 完全一致,可靠,保序。
有趣的是,反过来也一样,如果时间倒着走,TCP 也可看作 QUIC 的优化。
假设一开始没有TCP,而 QUIC 早已被部署,稳定运行了30年,今天突然有人提出 TCP (指1984年的 TCP,没拥塞控制,没 SACK,没时间戳,更没 RACK,只有GBN)会怎样。
一定会轰动业界,造成的爆炸效应肯定必今天 QUIC 造成的效应大得多。
人们肯定会高呼 TCP 优化了 QUIC :
- 人们惊讶于 TCP 竟然用如此集约紧凑的协议头表达完成的可靠,保序的语义。
- 人们惊讶于 GBN 和 RTO 竟然可以如此简单保证可靠传输。
- 人们惊讶于快速重传竟然可用收到连续3个重复 ACK 来启发。
- 人们惊讶于 TCP 滑动窗口竟然同时完成了保序和流量控制。
- …
这一切惊讶得益于,人们发现传输的 Packet 竟可以和 TCP 语义的字节流合在一起考虑,直接传输字节流。
TCP 去掉了 QUIC 数据保密性,完整性,TCP 说,这是应用自身的责任,TLS 至多是传输层的安全附加。
简直太妙了,TCP 实现了 QUIC 的语义,却如此瘦身,这是最完美的优化!且等,还有呢…
TCP 每次建立连接都需要握手和挥手,服务端不需保存任何 session,解放了维护成本。
TCP 为每条字节流维护独立的连接状态,状态机完美闭环。独立的连接状态使具有 PHB(逐跳行为) 功能的设备更容易识别和操作字节流。
精炼的 TCP 不能再多,也不能再少,非常稳定,TCP 作为公分母内置于操作系统,应用再不用自己链接传输协议。
人们看不到 TCP GBN 和 RTO 导致的拥塞崩溃,人们也看不到滑动窗口的队头阻塞,所有细节都被忽略了,人们毅然抛弃 QUIC ,拥抱 TCP。
几年后的一次大拥塞崩溃,TCP 加入了拥塞控制,再然后提出了 SACK 以优化重传效率,再然后…直到人们认识到 QUIC 解决了 TCP 的几乎所有这些问题。
这是一条咬尾蛇。
QUIC 是 TCP 的性能优化吗?若不总想着性能,TCP 是 QUIC 的优化吗?毕竟 QUIC 很多臃肿操作在 TCP 中都可以用相当精简的方式完成。
如果只考虑吞吐,QUIC 比 TCP 优秀,说到资源占用,TCP 就更好。但凡说 TCP 过时的,都是针对某个特性,比如 TCP 不适合传输直播流,确实不适合。比如 TCP 下载大文件效率偏低,确实偏低,但远程登录就很适合。
有趣的来了,如果整体考虑,无论从 TCP 到 QUIC,还是从 QUIC 到 TCP,或自研有损传输协议,再怎么优化,损耗在整体上是守恒的:
- QUIC 协议头越复杂,载荷率越低,有效载荷之外都是损耗。
- TCP 精简,弱表达能力会误判,无效重传的带宽侵占和延误重传的时间浪费都是损耗。
- FEC 丢包之前侵占有效带宽,ARQ 在丢包之后重传侵占有效带宽,都是损耗。
- 有损传输损失信息本身就是损耗。
损耗是固有的,也是有趣的,看用什么代价去交换,用资源可换,用时间也可换,或干脆接受损耗,但绝对不能消除损耗。
QUIC,TCP,其它各种传输协议,都在以不同的方式应对(输入法出现的是“硬怼”,也行)损耗,而固有的损耗是香农极限决定的:
香农极限(或称香农容量)指的是在信道上进行无差错传输的理论最大传输速率,是香农定理在有限带宽的信道上的理论。换句话说,当信号传输速率尚未达到香农极限时,可以找到零错误率的编码方法。
那么尚未达到极限时又如何呢?尚未达到的浪费本身即另一种损耗。
经理很注重自己的发型,经理每几个月就会去理一次发。
浙江温州皮鞋湿,下雨进水不会胖。