与延迟的斗争

1. 延迟、带宽与网络性能

性能是每一个工程师不懈的追求。现代 Web 应用中,每次交互行为都有可能伴随数个请求发出、数百字节数据交换。为了能够快速的做出响应,提高网络性能对 Web 应用来说尤为重要。

对于网络性能来说,延迟和带宽是最为重要的两个决定因素。根据 SPDY 协议的开发者之一 Mike Belshe 的一项研究:当带宽超过 5Mbps 时,继续增加带宽对 Web 网络性能的影响非常有限;而降低延迟却能够获得持续、线性的性能提升。不难发现,对于现代 Web 应用来说延迟已经取代带宽成为网络性能的瓶颈,如何降低延迟也理所应当的成为近年来工程师们关注的焦点问题。

2. 延迟的产生

网络延迟是由很多因素导致的。物理层面,信号的传播速度是存在极限的,例如中国与美国西海岸跨越太平洋的直线距离约 15,000km,按照光在光纤中的速度为 200,000km/s 计算,信号从中国发送至美国大约需要经历 75ms,往返就需要约 150ms。

除了物理层面的限制,网络传输还离不开路由与交换设备。数据在这些设备中进行路由或交换操作也需要消耗时间,如果不巧遇到设备吞吐量不足,发生排队也是经常会发生的情况。一般地,网络设备会对数据交换造成几十到上百毫秒不等的延迟。

「横跨半个地球进行通讯的延迟也不超过 300ms,看起来延迟也没有那么可怕嘛!」如果你这样想,就大错特错了:上面提到延迟的只是网络层完成一次双向通讯所带来的延迟(称作 RTT,Round-Trip Time),为了完成数据传输,每层网络协议都可能进行数次双向通信,这将会造成应用层的延迟是 RTT 的数倍。以一次 HTTPS 请求为例,我们来看看 RTT 会如何被放大:

  • DNS 解析 —— 1RTT
  • TCP 握手 —— 1RTT
  • TLS 握手 —— 2RTT
  • HTTP 请求 —— 1RTT

一次再平常不过的 HTTPS 请求需要消耗 5RTT,若以中美之间的 RTT 计算,完成一次 HTTPS 请求的时间将达到 1500ms,这样的延迟足以让用户从当前的上下文中分神。

大致了解了延迟是如何产生的,就可以有针对性的进行优化了。

3. 突破物理极限——内容分发网络

时间 = 距离/速度这一再简单不过的公式告诉我们:要想获得更快的时间,只能减少距离。通过简单的测试不同物理距离的服务器也可以看到,距离更近的服务器确实拥有更好的延迟表现:

不同服务器的延迟测试

上图为从上海分别对北京(baidu.com)和上海(ele.me)的服务器的延迟进行测试,可见访问两台服务器的延迟数据有数量级的差距。

如何让不同地域的用户都能有比较短的物理距离呢?答案就是内容分发网络技术,也就是我们通常所说的 CDN。CDN 通过在不同的区域、不同运营商部署服务器,配合全局负载技术,让用户能够从距离最近的服务器上获取数据,避免地域、运营商、网络拥堵等问题带来的延迟,提供流畅的用户体验。通过多点 ping 工具访问一个 CDN 域名(ss1.bdstatic.com)可以看到:世界各地的请求被分配到 29 个 CDN 节点进行处理,最终得到了 136 个检测节点平均 34.1ms 的延迟数据,国内的大多数检测节点延迟更是可以控制在 10ms 以内,优化效果非常明显。

除了降低延迟,CDN 还可以缓解核心网拥堵,实现异地灾备以及对流量进行更灵活的分配。经过 20 多年的发展,CDN 已经成为一项非常成熟的技术,也成为了互联网的一项基础设施。

4. 降低人为影响——网络协议升级

通过 CDN 搞定了 RTT,下面需要做的就是减少 RTT 的次数。要知道作为互联网基础的几个网络协议大多已经存在了几十年的时间,几十年沧海桑田这些协议的部分特性已经很难适应目前的网络环境,对这些协议进行升级也是对抗延迟的重要一环。

这其中不得不谈到的一个升级是 TLS 1.3。从上文对一次 HTTPS 请求的耗时分析可以看到,TLS 握手消耗了 2RTT,这在分毫必争的现代网络应用中显然是不能接受的,因此 TLS 1.3 应运而生。除了进一步增强安全性,彻底解决 TLS 1.2 中的攻击风险,TLS 1.3 更是将握手时间缩短至了 1RTT,而在会话恢复场景中更是可以实现 0RTT 握手,绝对可以称得上一次巨大的性能提升。有关 TLS 1.3 如何实现 0RTT 以及其他更新内容,可以参考 Cloudflare 的这篇文章,这里就不展开讨论了。

除了 TLS,其他的协议也都有自己的优化策略。例如 DNS 缓存、TCP Fast Open、HTTP 2 多路复用等等,在这些优化的加持下,一次 HTTPS 的请求可以达到 1RTT,也就是说传输层在保证安全与可靠的前提下实现了 0RTT!

5. 追求极致体验——应用逻辑优化

对速度的追求是没有终点的,毕竟没有用户会抱怨速度太快。那么如何还能再 1RTT 的情况下让速度更快呢?答案很简单:走在用户前面——进行预测加载。

预测加载不是一项新鲜的技术,它已经存在于我们日常使用的工具中。以我们最常使用的浏览器为例:开始一次请求过程并不是发生在输入地址并按下回车键之后,大多数情况下当我们在地址栏中输入第一个字符开始,浏览器就开始预测我们希望访问的站点并进行域名解析了,说不定在你按下回车键之前,浏览器已经帮你准备好了所有资源。

在 Web 的开发中我们也可以非常方便的进行预测加载。通过 link 标签,我们可以告诉浏览器为我们预先进行资源准备,并且可以指定不同的优先级。针对不同优先级的资源,浏览器会采取预加载、预连接、预解析等不同的处理方式。合理使用预测加载能够使 Web 应用获得超乎想象的体验优化。

6. 尾巴

技术的发展没有暂停键,网络技术更新的浪潮永远不会停止,只会越来越快。作为这场浪潮的参与者,我们要时刻准备好迎接新的挑战;而作为这场浪潮的见证者,我们更应该享受技术的便利,享受日新月异的美好。