换成 HTTP/3,弱网就能变好吗?

0 阅读7分钟

页面标题已经出来了,图片还空着,评论区也一直在转。检查网络,发现有丢包。讨论到最后,有人提议:“换 HTTP/3 吧,弱网下表现会更好。”

这个方向有依据,但还少了半句话:原来的等待,究竟是哪种机制造成的?

HTTP/3 可以减少某些请求之间的连带等待。如果页面慢在服务端处理,或者必须等一个业务结果才能发起下一个请求,换协议不一定能解决眼前的问题。

理解它的价值,不需要从报文格式开始。先看看几份互不相关的数据,为什么会被迫一起等。

换协议,换的是怎样运送数据

打开页面、查询订单、提交内容,这些是应用想完成的事。HTTP 约定请求和响应怎样表达;下面的传输机制,负责让数据在两端之间传递。

HTTP/2 通常通过 TCP 传输。HTTP/3 使用 QUIC,而 QUIC 的数据包通过 UDP 承载。这里先记住关系就够了,不必把每个缩写都背下来。

一次协议升级,可以改变建立连接和运送数据的方式,却不会自动改变业务流程。服务器原来要查完库存才返回结果,升级后仍然要等库存查询。

打个比方,换了配送方式,可能少在路上耽搁,但厨房还没做好的菜依然送不出来。

HTTP/2 明明能并发,为什么还会一起卡?

假设一个页面同时加载图片和评论,两条请求复用了同一个 HTTP/2 连接。它们的数据可以交错传输,不必等整张图片下载完,评论才开始走。

问题在更下面:TCP 向上提供的是一条按顺序交付的字节流。

如果中间一段数据丢失,后面已经到达的字节通常需要先等缺口补齐,才能继续按序交给上层。TCP 不知道这部分属于图片,那部分属于评论。于是,丢失发生在一个位置,受影响的却可能是同一连接里的多个 HTTP/2 流。这是传输层队头阻塞的一种表现。

注意范围是“同一连接”。其他连接未必跟着停,已经交付给应用的数据也不会倒退回去。不能把一次丢包描述成整个 App 的所有请求都被冻结。

HTTP/3 把哪些等待分开了?

QUIC 知道数据分别属于哪些流。每个流可以独立组织自己的顺序,不需要让所有流共用一条全局按序交付的字节队列。

回到图片和评论的例子:如果缺失数据只影响图片所在的流,评论流的数据又已经完整到达,就不必仅仅因为图片的缺口而一起等待。

可以把它想成分别叫号取件。某个人的包裹还没齐,其他人拿到了完整的包裹,可以先走。

不过,同一个网络包里也可能带着多个流的数据。这个包丢了,涉及的几个流都可能需要恢复。独立的流也仍然共用网络容量,不是每个流都多出了一条物理线路。

因此,HTTP/3 值得期待的是减少这类跨流阻塞,而不是让每次丢包都只影响一个请求,更不是让丢包没有成本。

用了 UDP,不代表缺了内容也算传完

听到 UDP,有人会担心:“它不是不保证可靠的吗?图片会不会缺一块也照样交上来?”

UDP 本身不提供 TCP 那样的可靠有序字节流,但上面运行的协议可以补上相应机制。QUIC 的可靠流会跟踪数据、发现缺失并恢复,接收端按流中的顺序向应用提供数据。HTTP/3 的请求和响应使用这种流,并不是把正文随便塞进几个 UDP 包就不管了。

可靠也不等于一定成功。网络长期不可用,连接仍然可能超时或失败。协议能尝试恢复传输,不能保证路径永远存在。

传输成功与业务完成之间也仍有区别。订单是否创建、任务是否取消,这些要由业务层确认,不能因为连接使用了 QUIC 就省掉原来的状态处理。

有些等待,换成 HTTP/3 还是绕不过去

最直接的是单个流内部的缺口。一份响应的前半段还没齐,后续内容即使到了,也不能总是直接交给需要按序读取的应用。

还有共同的拥塞。QUIC 需要进行丢包恢复和拥塞控制;共享路径上的可用容量有限,流量受限时,多个流仍可能一起变慢。减少按序交付造成的阻塞,不等于取消发送速率上的约束。

业务依赖则更容易被忽略。评论请求如果必须等用户信息回来才发出,前面的请求没完成,后面的请求根本还没进入网络。传输层没法替应用打破这条依赖。

HTTP 层本身也可能有等待,例如响应头压缩依赖尚未到达的信息。所以“HTTP/3 消除了所有队头阻塞”这个说法太宽泛。

如果一次页面加载主要在这些地方耗时,升级后的差异可能不大。这个结果并不奇怪,也不能据此认定新协议没有价值。

配置里开启了,不代表这次请求真的用了

客户端、服务器或边缘节点需要支持并成功协商 HTTP/3。网络还得允许相应的 QUIC 流量通过。

有些网络会阻断 UDP,导致连接无法建立。HTTP/3 规范建议客户端在这种情况下尝试基于 TCP 的 HTTP 版本;具体多久开始尝试、用户会多等多久,仍要看实现并实际测试。

因此,比较结果前要确认实际协商的协议。不能因为服务器开了 HTTP/3,就给所有请求都贴上 HTTP/3 标签;也不能把失败后的回退结果,当成 QUIC 正常传输时的表现。

回退测试同样重要。正常网络快了一点,但某类网络下先空等很久才切换,部分用户的总体体验反而可能变差。

怎样测,才能知道收益来自哪里?

可以先保持业务、资源大小和服务端处理一致,再设计几组有明确目的的对照:

场景想回答的问题
单个请求,正常网络与受控丢包单条传输的表现怎样,不把差异直接归因于跨流隔离
同一连接上多个独立请求某些数据恢复期间,其他请求能否继续完成
大响应与小响应并存用户需要的小结果是否仍被明显拖慢
UDP 不可用是否成功回退,失败或回退前额外等待多久

弱网工具的协议范围要一起核对。如果测试只对 TCP 施加丢包,而 QUIC 走 UDP,HTTP/3 看起来更快,可能只是它没有受到相同损伤。

相同丢包比例也不代表两种协议恰好丢掉相同的业务内容。包的组织、发送节奏会不同,需要多轮比较,不能用一轮随机结果断言谁一定更好。

冷启动连接与已经复用的连接最好分开记录,缓存状态也要一致。若两种协议实际访问了不同的服务节点,就应说明这个差异,不能把所有改善都算作协议收益。

最后看用户可见的结果:首屏何时可读,小请求何时完成,有多少失败,以及回退花了多久。协议日志用来解释过程,不能替代这些结果。

升级结论可以写得很具体:在多个独立请求并发、出现某类丢包时,等待缩短了;在服务端处理占主导的流程里,差异不明显;某些网络仍需要回退。

这样的结论比“HTTP/3 弱网更快”多了几个条件,却能告诉团队,下一步该继续调整传输,还是回头处理那个一直没完成的业务请求。(文章含AI辅助内容)