如何模拟弱网条件 - 限流, 丢包, 延迟和抖动

文章介绍了在不同操作系统中模拟弱网环境的方法,包括使用iperf3进行网络性能验证,Windows上的Clumsy模拟丢包、延迟,Mac的NetworkLinkConditioner以及Linux的tc工具进行流量控制。这些工具和方法有助于开发者在实际开发中针对性地优化网络通信性能。
摘要由CSDN通过智能技术生成
Abstract弱网条件的模拟
AuthorsWalter Fan
Categorylearning note
Statusv1.0
Updated2023-02-16
LicenseCC-BY-NC-ND 4.0

概述

在网络会议,实时通信,网络直播中,由于网络不稳定造成的卡顿,花屏,模糊屡见不鲜,这样不稳定的网络我们称为弱网。
需要采取诸如拥塞控制,重传,纠错等手段进行优化。

实际开发中,我们碰不到客户所遇到的各种网络问题,必须通过一些工具和手段来模拟弱网条件,从而有针对性的进行调优。

验证

在开始模拟弱网,进行网络限制之前,有必要用 iperf3 来验证我们实施的网络限制是否生效

  • 在服务器端启动 iperf3 server
iperf3 -s -i 3s -V -f m -p 12000
  • -s, --server: 以服务器模式启动

  • -f m: 显示带宽的单位为 m

  • -p 12000: 指定侦听的端口

  • -V --verbose: 输出更多的细节

  • 在客户端启动 iperf3 client,这里我们用 udp 方式来传输数据, 这样可以观察到丢包的数据

iperf3 -c 10.224.84.89 -p 12000 -w 5m -b 10m -t 300s -i 3s  -u -l 1000
  • -c: 作为客户端连接服务器
  • -w 5m: 设置 socket 的缓存大小
  • -b 20m: 设置发送数据的比特率(带宽)
  • -t 300s: 持续时间为 300秒
  • -i 3s: 每隔3秒显示报告
  • -u: 用 UDP 传输
  • -l 1000k: 设置读写的缓存大小,TCP 默认是 128 KB,UDP 默认是 8 KB

具体参见 https://iperf.fr/iperf-doc.php#3doc

在服务器端的显示结果如下, 我们可以观察到传输过的数据量,带宽,抖动以及丢包率

Linux ubuntu 4.15.0-180-generic #189-Ubuntu SMP Wed May 18 14:13:57 UTC 2022 x86_64
-----------------------------------------------------------
Server listening on 12000
-----------------------------------------------------------
Time: Thu, 16 Feb 2023 06:54:46 GMT
Accepted connection from 10.224.85.58, port 37666
      Cookie: ubuntu.1676530537.883608.68ec4248520
[  5] local 10.224.84.89 port 12000 connected to 10.224.85.58 port 55932
Starting Test: protocol: UDP, 1 streams, 1000 byte blocks, omitting 0 seconds, 600 second test
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  5]   0.00-3.00   sec  6.92 MBytes  19.4 Mbits/sec  0.005 ms  0/7257 (0%)
[  5]   3.00-6.00   sec  7.15 MBytes  20.0 Mbits/sec  0.014 ms  0/7500 (0%)
[  5]   6.00-9.00   sec  7.15 MBytes  20.0 Mbits/sec  0.013 ms  0/7501 (0%)
[  5]   9.00-12.00  sec  7.15 MBytes  20.0 Mbits/sec  0.016 ms  0/7499 (0%)
[  5]  12.00-15.00  sec  7.15 MBytes  20.0 Mbits/sec  0.018 ms  0/7501 (0%)
[  5]  15.00-18.00  sec  7.17 MBytes  20.0 Mbits/sec  0.047 ms  0/7514 (0%)

Windows

在 windows 系统中,我们可以使用 clumsy 来模拟弱网条件,更改网络状况, 引入延迟(lag),丢包(drop),乱序等

Mac

在 MAC 系统中, Network Link Conditioner 是一个很好用的工具,您可以从 Apple Developers 页面下载,可通过 System Preferences 访问。它可以限制上行或下行链路的带宽、延迟和数据包丢失率。

安装说明参见 https://nshipster.com/network-link-conditioner/#installation

Linux

在 Linux系统中, tc(Traffic Control)是最常用的网络控制工具,它既强大又复杂, 我们常用 netem 模块和 tc 命令常用来控制网络流量,模拟网络中常见的各种问题。

tc 用于在 Linux 内核中配置流量控制。流量控制包括以下内容:

  • SHAPING 整形

当流量被整形时,它的传输速率是受控的。 整形可能不仅仅是降低可用带宽 - 它还用于平滑流量突发以获得更好的网络行为。 整形发生在出口处。

  • SCHEDULING 调度

通过调度数据包的传输,可以提高需要它的流量的交互性,同时仍然保证批量传输的带宽。 重新排序也称为优先级,仅发生在出口处。

  • POLICING 监管

整形处理的是流量的传输,而监管则与到达的流量有关。 因此,监管发生在入口处。

  • DROPPING 丢弃

超过设定带宽的流量也可以立即被丢弃,丢弃可发生在入口和出口处

流量的处理由三种对象控制:

  1. qdiscs : 简单来说,它可以理解为一个队列,以及入队出队的调度器,默认的调度器是 FIFO, 包括可分类和不可分类的 qdisc
  2. classes: 类存在于 classful qdisc 中,它可以包含多个子类或单个子 qdisc, 可用于极其复杂的场景
  3. filters: 过滤器 filter 是Linux流量控制系统中最复杂的组件,它提供了一种方便的机制,可以将流量控制的几个关键元素粘合在一起

关于 TC 的内容,三天三夜也讲不完,需要另外详细阐述,略过不表。

通过一些例子来看看怎么使用 TC

Loss 丢包

  • 增加 loss
sudo tc qdisc add dev eth0 root netem loss 20%
  • 更改 loss
sudo tc qdisc change dev eth0 root netem loss 30%
  • 删除 loss
sudo tc qdisc del dev eth0 root netem loss 30%

Jitter 抖动

  • 增加jitter 到 50ms
sudo tc qdisc add dev eth0 root netem rate 1000mbit delay 0ms 50ms 0%
  • 更改jitter 到 100ms
sudo tc qdisc change dev eth0 root netem rate 1000mbit delay 0ms 100ms 0%
  • 删除 jitter
sudo tc qdisc del dev eth0 root netem rate 1000mbit delay 0ms 100ms 0%

速率控制 Rate Control (带宽限制)

  • 限制 rate 到 1mbps
sudo tc qdisc add dev eth0 root netem rate 1mbit

叠加多种限制条件 Impairments

  • 使用 handle 1: 增加 rate control at root qdisc:
sudo tc qdisc add dev eth0 root handle 1: netem rate 1mbit
  • 串接 500ms jitter 到 rate control qdisc handle 1:
sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem rate 1000mbit delay 0ms 500ms
  • 串接 5% 的丢包到 jitter qdisc
sudo tc qdisc add dev eth0 parent 10:1 netem loss 5%

inbound traffic 输入流量的限制

刚才说的都是输出流量的限制,tc 很容量来控制发送的速率,延迟和丢包,但是对于输入流量,需要引入一个虚拟网卡, 数据流向是 “client --> ifb --> nic --> server” , 其中 ifb 是虚拟网卡,nic 是真实网卡,我们用 tc控制 ifb 到 nic 之间的发送, 来达到网络限制的目的。

  • 先用 modprobe ifb 命令来启动相关的内核模块, 以创建虚拟接口,代表输入的流量
modprobe ifb
  • modprobe ifb 默认创建两个 ifb 设备 ifb0 和 ifb1.
    它位一开始的状态是 "down", 需要用以下命令启用
ip link set dev ifb0 up
  • 如果上述命令失败,需要输入以下命令后重试上一步
ip link add ifb0 type ifb
  • 在网络接口上启用 ingress 并使用 filter 将所有输入的流量重定向到虚拟的 ifb 设备
tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
  • 在虚拟 ifb 设备上应用网络限制,就像在普通的网络设备上一样
tc qdisc add dev ifb0 root netem delay 750ms
  • 显示当前的网络设置
sudo tc qdisc show
  • 删除所有的网络限制
sudo tc qdisc del dev eth0 root

如果嫌命令太烦琐,可以用如下的脚本来做网络限制 netimpair.py
(这个版本有点老,我做了一些改动,回头 fork 一个 git repo 提交上去)



本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值