Highlight
Apple 将 app 响应性拆成往返时长和往返次数两个因素,并给出 HTTP/3、QUIC 迁移、QUIC datagrams、服务器缓冲区调优和 L4S 兼容性测试这些可落地的降延迟方法。
核心内容
很多网络问题看起来像带宽不足。视频会议卡顿、屏幕共享延迟、视频跳转后长时间 rebuffer,用户第一反应往往是升级宽带。Session 一开始就给出反例:带宽从 1Mbps 提到 2Mbps 时,页面加载时间下降接近 40%;超过 4Mbps 后,继续增加带宽几乎不再改善页面加载时间。相反,延迟每下降 20 毫秒,页面加载时间会线性改善(03:24)。
真正拖慢 app 的,是每一次 round trip 的时长,以及完成一次请求需要多少个 round trip。队列通常堆在网络里最慢的链路上,新包必须排在旧包后面。TLS 1.2 over TCP 取得第一个响应包可能需要 4 次往返;当每次往返都被队列放大,首包时间就会变得很长(02:16)。
Apple 给出的路线分三层:app 侧减少往返次数,服务器侧减少无意义排队,网络侧测试 L4S。app 只要使用 URLSession 和 Network.framework,在服务器开启后就能自动使用 IPv6、TLS 1.3 和 HTTP/3;如果使用 QUIC,还可以启用连接迁移和 datagram flow(04:45)。
服务器同样会制造延迟。Session 用 WWDC 视频随机跳转作为例子:服务器 TCP、TLS、HTTP 缓冲区分别配置到 4MB、256KB、4MB,新生成的数据包被排在旧数据后面,导致视频跳转后长时间黑屏。把 HTTP、TLS、TCP 缓冲区降到 256KB、16KB、128KB 后,再次跳转可以立即恢复播放(09:36)。
详细内容
采用 HTTP/3 并启用连接迁移
(06:03)移动设备经常从 Wi-Fi 切到蜂窝网络。普通连接需要重新建立,app 会短暂停顿。HTTP/3 基于 QUIC,支持连接迁移。对于 URLSession,Session 给出的 opt-in 方式很短:
let configuration = URLSessionConfiguration.default
configuration.multipathServiceType = .handover
关键点:
URLSessionConfiguration.default创建默认会话配置,后续请求可以继续走系统网络栈。multipathServiceType = .handover允许连接在网络切换时迁移,目标是减少 Wi-Fi 到蜂窝切换时的 stall。- 服务器需要支持 HTTP/3;app 侧使用
URLSession后,协议选择由系统在可用时处理。
如果你直接使用 Network.framework 创建 QUIC 连接,同一能力配置在 NWParameters 上:
let parameters = NWParameters.quic(alpn: ["myproto"])
parameters.multipathServiceType = .handover
关键点:
NWParameters.quic(alpn:)创建 QUIC 参数,alpn用来声明应用层协议名称。multipathServiceType = .handover开启 handover 模式,让连接在网络变化时尽量保持连续。- Session 建议启用后用自己的 app 验证,因为连接迁移需要和实际协议、服务器部署一起测试。
用 QUIC datagrams 替代直接使用 UDP
(06:39)如果自定义协议直接使用 UDP,iOS 16 和 macOS Ventura 提供了 QUIC datagrams。它们保留 datagram 的使用方式,同时会响应网络拥塞,帮助维持较低 round-trip time,并减少丢包。
// Only one datagram flow can be created per connection
let options = NWProtocolQUIC.Options()
options.isDatagram = true
options.maxDatagramFrameSize = 65535
关键点:
- 注释说明每个连接只能创建一个 datagram flow,这会影响协议设计。
NWProtocolQUIC.Options()创建 QUIC 协议选项。options.isDatagram = true声明该 QUIC flow 使用 datagram 模式。options.maxDatagramFrameSize = 65535设置允许的最大 datagram frame 大小。- 创建 datagram flow 后,可以像普通 QUIC stream 一样发送和接收数据。
用 networkQuality 找出服务器排队
(07:49)macOS Monterey 引入的 network quality tool 可以测服务商网络,也可以测你自己的服务器。做法是先把服务器配置成测试目的端,然后分别测 Apple 默认服务器和自有服务器。如果默认服务器得分好,自有服务器得分差,问题很可能在服务端排队。
networkQuality -s -C https://myserver.example.com/config
关键点:
networkQuality是 macOS 的网络质量测试工具。-s让工具按服务器测试模式运行。-C https://myserver.example.com/config指向你的测试服务器配置。- Session 建议用默认服务器和自有服务器各跑一次,比较响应性得分。
Apple 还列出了可用于外部验证的三个测试入口:
https://www.waveform.com/tools/bufferbloat
https://github.com/network-quality/goresponsiveness
https://www.speedtest.net/
关键点:
- Waveform 提供 Bufferbloat test,用来观察排队导致的延迟。
goresponsiveness是 responsiveness test 的 Go 开源实现。- Ookla Speedtest app 增加了 responsiveness measurement,并展示 round-trip time。
调小服务器缓冲区
(09:36)Session 的视频跳转案例里,服务器缓冲区太大。新数据被旧数据挡住,用户看到的是 rebuffer。Apple 在 Apache Traffic Server 中降低 TCP、TLS、HTTP/2 的缓冲行为:
% cat /opt/ats/etc/trafficserver/records.config
# Set not-sent low-water mark trigger threshold to 128 kilobytes
CONFIG proxy.config.net.sock_notsent_lowat INT 131072
# Set Socket Options flag to the sum of the options we want
# TCP_NODELAY(1) + TCP_FASTOPEN(8) + TCP_NOTSENT_LOWAT(64) = 73
CONFIG proxy.config.net.sock_option_flag_in INT 73
...
# Enable Dynamic TLS record sizes
CONFIG proxy.config.ssl.max_record_size INT -1
...
# Reduce low-water mark and buffer block size for HTTP/2
CONFIG proxy.config.http2.default_buffer_water_mark INT 32768
CONFIG proxy.config.http2.write_buffer_block_size INT 262144
关键点:
proxy.config.net.sock_notsent_lowat把 TCP not-sent low-water mark 设为 128KB。sock_option_flag_in组合启用TCP_NODELAY、TCP_FASTOPEN和TCP_NOTSENT_LOWAT。proxy.config.ssl.max_record_size INT -1启用动态 TLS record sizes。proxy.config.http2.default_buffer_water_mark降低 HTTP/2 low-water mark。proxy.config.http2.write_buffer_block_size调整 HTTP/2 写缓冲块大小。- 如果使用其他 web server,需要寻找等价配置,而不是照搬 ATS 配置名。
测试 L4S 兼容性
(14:50)L4S 是 Apple 与网络社区合作推进的低延迟技术,在 iOS 16 和 macOS Ventura 中以 beta 形式提供。它通过显式拥塞信号让发送端调整速率,目标是保持短队列并实现 zero congestion loss。
在 macOS Ventura 上,可以用 Session 给出的 defaults 命令开启测试:
defaults write -g network_enable_l4s -bool true
关键点:
defaults write -g写入全局偏好设置。network_enable_l4s是 macOS Ventura 中用于开启 L4S beta 测试的开关。-bool true将该开关设为开启。- iOS 16 中对应入口在 Developer settings。
- 如果用 Linux server 测试 QUIC,QUIC 实现需要支持 accurate ECN 和 scalable congestion control algorithm。
核心启发
-
为视频或直播服务增加服务器响应性巡检:把
networkQuality -s -C接入上线前检查。先测 Apple 默认服务器,再测自有服务器。两者差距大时,优先检查 TCP、TLS、HTTP 缓冲区。 -
给实时协作 app 增加网络切换测试用例:在 Wi-Fi 和蜂窝之间切换,观察正在进行的请求或 QUIC 连接是否 stall。
URLSessionConfiguration.multipathServiceType = .handover是最小入口。 -
把自定义 UDP 协议迁移到 QUIC datagrams 试验分支:保留 datagram 数据模型,用
NWProtocolQUIC.Options开启 datagram flow,再验证拥塞场景下的 round-trip time 和丢包变化。 -
为屏幕共享或远程控制 app 建立 L4S 兼容测试:在 iOS 16 Developer settings 或 macOS Ventura defaults 开启 L4S,跑真实交互流程,记录菜单响应、光标移动和画面更新时间差。
-
把 RPM 当成网络体验指标:Ookla 展示 round trip time 后,可以用
60000 / RTT(ms)得到 round trips per minute。这个指标比单纯下载速度更贴近视频会议、屏幕共享和搜索建议的体验。
关联 Session
- Improve DNS security for apps and servers — 同属网络基础能力,讲 DNSSEC 与加密 DNS 如何保护 app 和服务器通信入口。
- Deliver reliable streams with HLS Content Steering — 面向流媒体服务端调度,和本 session 的视频服务器响应性案例相互补充。
- Create a more responsive media app — 聚焦媒体 app 的响应体验,可和网络侧延迟优化一起使用。
- Meet ScreenCaptureKit — 屏幕共享是 L4S 演示中的典型低延迟场景,ScreenCaptureKit 负责捕获侧性能。
评论
GitHub Issues · utterances