HTTP/3 标准化了,什么时候 QUIC 能插遍全球?
没有那么快,甚至非常困难。
我有很多传输协议优化的想法,偶尔也实现几个,但这是走火入魔了,没普遍意义。设计或优化一个协议很容易,但部署一个协议非常困难。
TCP 的问题就在那里,如何解决它们显而易见,十个人能有十个方案。但让所有人同意你的新协议替换 TCP,需要动机,无论是技术的,还是经济的。最好的结果,大概率也是共存。
部署 QUIC 的阻力:
被提到最多的就是运营商对 UDP 不友好了。
在绝大多数情况下,任何不友好都是在嫌弃管理成本太高。
除非 QUIC 形成一套标准管理接口,QUIC 的管理成本就不会下降,这种管理成本是部署 QUIC 的阻力。
所有管理,最终都要落实到对数据对象的管理,也就是数据结构的分配,查找,修改,销毁,归根结底就是 CPU 周期和内存,或者说时间复杂度和空间复杂度,也就是钱。
先看状态设备,如状态防火墙,NAT。
TCP 内置闭环状态机,网络设备可以利用状态机对 TCP 流量进行管理。收到 SYN 就创建一条流,收到 FIN 或 RST 就着手销毁一条流,这是一种被动管理,只要简单解析 TCP 头的标志就能实现对流量的操作。
而 UDP 没有任何状态可利用,如何管理数据结构全靠主动。比如创建一条流,若基于五元组识别 UDP 流,但 UDP 端口是可随时变化的,若基于其它字段识别,该字段标准化了吗?何时销毁一条流,只能靠定时器,那么超时时间是多久?
要么频繁创建新流消耗CPU周期,要么滞留已经不活动的僵尸流消耗内存,很难找到一个平衡点。
再看无状态设备,比如标准路由器,限速,防火墙,无状态负载均衡设备。
无状态设备一般也基于元组散列值来分类数据包,或基于精确的五元组进行匹配,UDP 可变的元组信息使这些设备很难高效甚至正确地工作。
无论是有状态设备还是无状态设备,对 UDP 流量均很难识别和施加控制,假设成功限制了一条 UDP 流,它将源端口换了,一切还要重来。
当管理成本很高时,一刀切是最最佳策略,对 UDP 流量,若不超阈值,放任通过,一旦带宽超阈值,就直接丢包,这就是为什么 UDP 快的时候能飞起,差的时候一塌糊涂的原因。
为保证 TCP 流量的 QoS,对 UDP 流量不友好就不难理解了。
QUIC 自身完美解决了流识别问题。QUIC 使用一个协商出来的 Connection ID 识别一条流,和五元组解耦。任凭地址端口如何转换,只要数据包能到达目的地,QUIC 就可以正确接收。
QUIC 流识别不再依赖固定元组,端甚至可主动变化地址端口支持移动性或隐蔽性,这意味着有关流识别及包分类的难题都甩给了转发设备。曾经基于固定元组的流识别和包分类机制都失效了。
QUIC 一般由内容提供商推荐部署,客户端从 QUIC 获得承诺的体验,内容提供商也因此获得流量,但运营商并未能获得直接收益,那么设备商和运营商有什么动机去升级改造呢?
除了运营商阻力,再看兼容性阻力。
自家 APP 连接自家服务器,这个好办,服务器和 APP 协调好节奏,AB 平滑升级即可。
可浏览器厂商该如何实现通用浏览器呢,是不是要先用 HTTP /3 先试一下,不行再 HTTP /2,再不行就 fallback 到 HTTP /1,这样做显然对只支持 HTTP /1 的服务不公平,不是服务性能差,而是浏览器兼容操作的锅,那么这种不公平是否能推动服务端升级呢?未必。
同时发起三个 HTTP 版本的请求,哪个先回来算哪个,感觉可以,但这种行为并不干净,互联网将充斥这种垃圾流量,特别是短连接,将会出现接近三倍的请求流量,QUIC 对短连接带来的收益确定大于三倍流量成本吗?未必。
QUIC 强调自己实现在用户态,这也是 QUIC 的卖点之一。但我觉得这反而是它的一大阻力。对于已有应用,为 QUIC 而升级的动机有多大?若要把一个 HTTP/TCP 应用迁移到 QUIC,难度可想而已。对新开发的应用而言,为支持其直接使用 QUIC,需要很多库,中间件直接提供 QUIC 接口,开发这些接口的动机有多大。
TCP 被诟病内置于操作系统,改 TCP 就要改操作系统,然而 QUIC 真的就能随意定制吗?修改操作系统可能改一次就够了,如果为 QUIC 修改库,修改中间件,库,中间件的升级工作量真的比操作系统工作量小吗?如果你升级过 libc,评估一下,升级 Linux 内核和升级 libc,哪个难度大?
同样的,QUIC 强调自己内置安全性,然而对于不需要安全性的应用而言,剥离安全性支持的难度和代价有多大?
假设以上所述,无论是运营商还是软件厂商,均无动机部署 QUIC,那么有人说了,如果 QUIC 足够好,必然会倒逼它们支持 QUIC 并部署 QUIC。so ?
最后,我们看看协议的普适性。
深入 QUIC 细节,QUIC 在高丢包,高乱序环境中解决了 TCP 解决不了的问题,无论与字节流分离的 Packet Number 还是独立的 ACK Frame,都以 TCP 无能为力的方式更精确判断丢包并更高效重传,同时,其内置的多路复用和改善后的滑动窗口可以让多条 Stream 并行不悖,解决了队头阻塞问题(虽然并不是那么彻底)。但这又能怎样?实际现网环境,以上优化措施对多少场景是刚需?
显而易见,上述优化措施对 Wi-Fi 弱网是多多益善,可 Wi-Fi 弱网也在逐渐变强。如果底层改善了,Wi-Fi 逐渐不弱了,QUIC 的优势还明显吗?
虽然 QUIC 无论在什么场景可能都比 TCP 好那么一点,但这差异会加强部署 QUIC 的动机吗?
TCP 虽性能不行,但足够通用,QUIC 并不通用,QUIC 只是声称在 TCP 做得不够好的地方它能做得更好,但也只是声称,并非承诺。在 TCP 已经够用的场景,QUIC 显然是没有必要的,比如远程登录,信令传输,pingpong协议。
显然,TCP 必然要和 QUIC 长期共存。有趣的是,只要目标不是彻底替换掉 TCP,这件事本身就是 QUIC 部署的最大障碍。即便是为了彻底替换掉 TCP,看看 IPv6 替换 IPv4 的进程就够了,多么明确的一个目标,但进展却如此缓慢,大概率这种替换是永远完不成的。
QUIC 并不是一个新协议,我把 TCP 称作 A,那么 QUIC 就是 A+,它只是针对 TCP 在某些场景下的某些痛点,针对性地解决问题,也正因为如此,QUIC 也只适合这些具有 TCP 痛点的场景,对于其它场景,虽好但不需要。
这还没提 QUIC 获得这些收益的代价。更复杂的协议头,更繁杂的解析,更高的 CPU 和内存,如果根本不需要或用不起那些或多或少的收益,付出这些值得吗?汤臣大平层降价50%,8000万到手,贵就是贵,还是买不起。
QUIC 相对于 TCP 的性能提升,本质上就是协议头表达能力增强的结果,RTT 测量更准,丢包判断更准,在正常无丢包情况,并无区别。这也就解释了为什么 QUIC 在弱网环境更优秀,在网络质量好时平淡无奇。
QUIC 并没有提升传输性能的下限,只是提升了上限,而上限并不是轻易可达的。
就像考试一样,能力决定分数上限,你的能力决定你考不了100分,但同样也考不了0分,无论怎么折腾,你的分数总是在胡乱猜答案的分数和你的能力上限分数之间徘徊。TCP 是70分,QUIC 就是80分,那么 TCP 的成绩总在 50~70 区间,而 QUIC 的成绩就在 50~80 区间。弱网看上限,好网络看下限,这就是根本。
TCP 可能永远都不会被替代,可能再也没有一个协议可以替代 TCP,可能 TCP 已经和 IP 一样了,正如它们本来就是在一起一样。
针对 TCP 的块数据传输痛点,QUIC 可能只是解决方案之一,对于直播流,QUIC 远不能胜任,可能还需要别的传输协议,但肯定和 TCP/QUIC 完全不同。
近日标准化的 HTTP /3,人们沸腾了起来,朋友圈,微博都在转发,甚至又有人翻出阿里的 XQUIC,千滚水PR,翻出 Akamai,日本运营商,Google … 我又要泼冷水了。
浙江温州皮鞋湿,下雨进水不会胖。