从互联网诞生开始,网络吞吐量的限制、数据分组的丢失、数据传输的延迟和延迟抖动等人为或意外的状况就紧紧的伴随着互联网的发展。而当今的互联网更是一个拥挤、繁忙和复杂的庞大系统,不同的网络服务和应用以竞争的方式共享相同的网络基础设施收发流量。对于那些传统应用场景,比如 Web 浏览、文件传输或音视频点播等服务,因为这些场景下用户对于延迟的容忍均在秒级甚至更大,而对网络抖动甚至无感知,所以使用传统的基于 cubic 或 reno 的 TCP 协议就能够较好的完成任务,这些拥塞控制算法倾向于塞满网络直到丢包发生然后极速退避,这就导致网络的拥堵程度总是处在剧烈的变化之中。
而以实时音视频传输需求为代表的实时网络场景更关注的是在可接受的音视频质量下更低的延迟,这就要求拥塞控制算法不能总将网络塞满而是要调整编码策略、发送在较低延时下可获得更佳主观体验所需码率的实时音视频数据,对于这点传统的 TCP 无法满足需求,虽然有基于 BBR 的 TCP 拥塞控制算法,但如果需要定制场景并与媒体层联动的时候就面临修改协议栈代码的问题,这对于新功能的发布和版本的快速迭代并不友好,因此目前在实时网络行业深耕的各家厂商基本都会使用到 UDP 协议 + 自研弱网对抗算法的搭配。实时网络产品依靠准确的带宽估计、高效的丢包对抗、合理的前向纠错等能力提高端到端通信质量、降低端到端通信延迟。而拥有可靠且高效的评价产品对于提升弱网对抗能力就变的至关重要。
实际网络的复杂性远超如下所列的范围:
实际可能的网络链路,数据流经历了各种网络节点和不同类型的设备和协议,不同设备的转发能力、转发延迟都不尽相同:
为了构建和建模实际网络,我们从实际网络中抽象出了一组参数,用以描述实际网络的损伤程度。被抽象为黑盒的网络链路:
用网络损伤仪提供稳定可控的弱网环境:
从对实际网络的探测和抽象来看,我们期望网损工具有以下功能:
从使用的便利性来看,期望网损工具有以下特性:
对于设置指定的网络损伤的参数,网损仪能够实现不同网络参数的准确模拟,能够在网络链路中添加定时定量的可靠网络损伤,能够提高网络状态的可控性和可复现能力。
对于设置什么样的网络损伤,使用什么样的参数,网损仪本身并不会给出答案。由于网络本身的复杂性,真实网络仅对观测者提供有限的可见性,而目前整个行业对网络损伤的探测方法和结果并不完备,所以目前市面上不同的网损工具支持的损伤功能和提供的损伤模型不尽相同,也不尽准确。
S****
这是一款商业网络损伤仪器,支持模块化构建网络拓扑,可以分别设置每个模块的损伤参数,软件内置常见的通信设备仿真组件。
该设备的特点是仿真参数精度高,拓扑构建灵活。同时也要求使用者对需要仿真的网络拓扑和其中的网络节点有比较清晰的认知,相当于去仿真一个接近白盒的网络链路。
自动化方面支持 Restful API 接口调用。
H****
这也是一款商业网络损伤仪,它将网络抽象为两个方向的链路分别添加指定损伤,可以通过 filter 将指定流量导入不通的链路中进行损伤,相比之下这种实现方式更加接近互联网的思维方式。
在试用这款设备的时候该款产品仍处在开发和高速迭代中,添加了不少对互联网行业更友好的特性,比如:更多丢包模型的支持,更多种类的 jitter 分布支持,Python 调用接口的开发等。
使用下来这款产品在 UI 交互和系统稳定性方面还有较大的提升空间。
这是腾讯 WeTest 开发的一款网络损伤工具,目前支持 iOS 和 Android 平台。该工具通过 VPN 的方法代理本机流量实现网络损伤的注入,更适合 Web 或普通类型 APP 开发的弱网测试需求,对于实时音视频这种流量较大的场景通过 VPN 代理的方式会导致明显的系统性能问题,使得仿真准确性下降。
该产品的特点是内置了不少弱网场景的模型,比如:电梯、高铁、地铁场站场景等,也会更新基于腾讯服务器探测到的实时延迟和 Jitter 作为仿真数据来源。
自动化方面 Andoid 平台支持 adb 方式的接口调用,iOS 平台目前还没有使用过。
这是一款小团队的开源软件,目前仅支持 Windows 平台使用。
这款软件的功能相对比较简单,甚至没有找到 Jitter 的设置方法。自动化调用方面也没有对应的接口支持。
但对于低成本的 Windows 单机弱网调试也算是填补了一个空白。
这款软件是作为 Apple 开发者工具存在的,分别支持 MacOS 和 iOS 设备。
功能方面也比较简单,除了带宽限制、丢包和延迟外也没有看到 Jitter 相关的设置,不过该工具支持一些简单的网络类型的预置,但实现比较简单。
该功能模块在不同版本的 Apple 系统中维护的较好,可用性和稳定性都比较有保证,UI 也比较简洁明了。
自动化方面可以通过 applescript 脚本控制,但控制精度较低,不适合高频调用。
大名鼎鼎的 TC 模块作为 Linux 内核的一部分存在,没有官方的 UI 界面适配。但江湖上流传着各种各样的 Wrapper 和第三方 UI。
因为 Linux 内核开源的特性使得 TC 拥有无尽的可能性,但缺点就是学习曲线比较陡峭,并且在不同内核版本中的功能实现有不小的差异,比如:pfifo 虽然文档中都声明支持,但大多数版本并不支持;甚至有些版本的 jitter 分布不符合预期。
当 TC 结合 iptables 之后,能实现绝大多数网损仪拥有的静态损伤功能;而对于动态的损伤受限于 Linux 命令执行的实效性调用的精度并不高。如果要提高执行精度就需要去直接调动 C 接口或直接进行编程实现。
实际工作中网络损伤环境的需求主要来自有两个方面:
探测和确认产品的弱网对抗能力边界
提高产品在实际网络中的弱网对抗能力
对于第一点需求,行业中一般的作法是将某一网络指标或几个网络指标的组合参数拉满,直到产品卡死或无法正常使用为止。例如可能的测试方法包括:带宽限制从 1000Kbps 逐步降低到 100Kbps 或 50Kbps;丢包率从 5% 上升到 70% 或 80%;延迟(或延迟抖动)从 10ms 上升到 2000ms。这种测试方法确实是有意义的,不过从对多种网络损伤设备的使用经验来看,不同设备的带宽限制功能默认配置的队列深度和允许的 Burst 数据量是不尽相同的,延迟抖动的默认分布和是否允许乱序的具体实现也有区别,所以即使是相同的带宽限制或相同的延迟抖动,用不同的网损工具很能可能会测试出不同的结果;而对于丢包率和固定延迟的指标来说各个工具的默认实现基本上是一致的,分别对应随机丢包和单位为毫秒的固定延迟。
对于第二点需求,问题的难点是如何描述和建模真实网络,可以看到一部分近期涌现的网络损伤软件比如 QNET 已经注意到这方面的功能了,开始集成一些对真实网络的探测数据和模型,但受限于产品本身的形态和平台限制在进行大规模部署和使用时还是有不少障碍。
针对以上提到的两个问题,声网分别开展了网络损伤特征的研究和实际网络探测和建模的持续推进,从目前网络探测的数据来看,实际网络的损伤有以下特征是传统弱网测试用例无法覆盖到的:
网络带宽的时变频率远高于直观,并且需要配合队列深度和突发流量的支持。
长时间持续的高随机丢包并不常见,大多数丢包与网络的拥堵状况具有很强的相关性且并不随机。
不存在持续的较低带宽限制,除非运营商或共享网络的人为设置。
基本不存在乱序或重复包的场景,除非在小区或 AP 切换的时候。
在对比了各种网络损伤工具的优劣势之后,声网最终选择了 Linux Traffic Control 的自研方案,目前来看这种方案的开放性和可能性是最高的,TC 命令 + iptables + 自研开发的组合完全能够覆盖从弱网对抗边界测试到实际网络仿真的各种应用场景,为声网产品在更真实的网络下验证弱网对抗算法提供有力的保障。
对于互联网公司,特别是有仿真 Lastmile 网络需求的公司来说,目前市场上的硬件网损仪适配的还不是太友好,传统的硬件网损仪从适配运营商和通信设备厂商的需求发展起来,更偏重于保障测试的吞吐量和仿真的精度,对于网络类型和网络场景的多样性缺乏探索,当前市场上也出现了一些软件的网损解决方案,有些仿真软件的开发过程中会利用网络探测结果内置一些网络场景和网络类型的模版,更贴合互联网公司的使用场景。对于弱网对抗要求不高的产品来说,选择这些软件仿真弱网是高效且低成本的方案,而对弱网对抗有较高要求的实时网络产品,在有能力做网络探测和订制网络损伤场景的前提下,使用开源的 Linux Traffic Control 是一种更加自主和具备更多可能性的选择。
附表:网络损伤工具功能对比
<点击图片查看大图>
Dev for Dev(Developer for Developer)是声网 Agora 与 RTC 开发者社区共同发起的开发者互动创新实践活动。透过工程师视角的技术分享、交流碰撞、项目共建等多种形式,汇聚开发者的力量,挖掘和传递最具价值的技术内容和项目,全面释放技术的创造力。