压测之接口lo的妙用

分享:  

问题背景

前一篇文章介绍了本地开发机压测时如何为每个待压测分配CPU资源(其实是taskset进行绑核,由于没有其他负载可以近似为分配CPU资源),本文继续介绍下如何让压测变得更真实一点,那就是网络IO这块,在本地通信时往往使用的是loopback接口,但是loopback并不是一个真实的网卡设备,它基本没有什么硬件网卡设备的传输速率的限制,也没有网络传输过程中的传输延迟。

这样的话,我们在压测的时候,网络方面的开销就几乎体现不出来,比如说,你想看下在4g网络下客户端、服务器之间网络通信数据包多大时打开数据压缩更有价值……

在我的测试过程中我希望能尽可能简化测试工作的同时,也能保证该有的环境的真实性,于是就有了本文对loopback接口的一点探索。

认识本地lo

Linux中的Loopback接口是一个虚拟网络接口,允许在同一主机上运行的应用程序之间通信。它通常被称为“lo”接口,具有IP地址127.0.0.1。

Loopback接口在内核中使用Loopback驱动程序实现,创建一个虚拟网络接口,并将所有传入的数据转发到本地协议栈。当一个应用程序将数据发送到loopback接口时,数据会被回送到协议栈,并像从另一个网络接口到达一样转发。 在Linux中,Loopback接口的一个重要用例是用于测试和调试网络应用程序。通过通过Loopback接口发送和接收数据,应用程序可以模拟网络流量,而不实际发送或接收来自物理或虚拟网络接口的数据。

Loopback接口还由一些网络协议使用,例如Kubernetes kube-proxy IPVS,OSPF和其他需要在同一主机上的进程之间通信的网络相关软件。

总之,Linux中的Loopback接口是一个虚拟网络接口,为在同一主机上运行的应用程序提供了一种通信通道。它在内核中使用Loopback驱动程序实现,并且在测试、调试和网络相关软件中具有许多实际用例。

认识netem

在 Linux 中,ip 命令中的 netem 是一个网络模拟工具。它允许您对网络连接进行各种修改,例如,添加延迟、丢包以及增加噪声等,以便在网络环境下测试应用程序的性能和稳定性。使用 netem 工具,您可以模拟各种不同的网络条件,包括高延迟、高带宽和低带宽等,以便更好地测试和优化应用程序在各种网络条件下的行为。

Netem 已经成为 Linux 网络模拟和测试工具的标准选择之一,同时也是在诸如交换机、路由器和 WAN 加速器等网络设备上进行隔离测试和仿真时的一个有用工具。通过使用 netem,您可以更好地了解您的应用程序在不同网络条件下的行为,并且能够更好地进行演示和培训。

利用本地lo

如何使用netem让本地loopback接口更好地模拟真实网络情况呢?下面就来简单说一下。

启用netem

首先,需要启用内核模块netem:

sudo yum install -y kmod
sudo modprobe sch_netem

模拟网络延迟

然后,如果loopback接口的每次的收、发操作模拟一定的网络延迟:

sudo yum install iproute-tc
or
sudo yum install iproute

sudo tc qdisc add dev lo root netem delay 1ms

这样的话就相当于一个rtt增加了2ms,为了验证这个,你可以在执行上述模拟前后,分别看下ping localhost的延迟。

模拟之前ping测试延迟:

sh-4.2# ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.047 ms
^C
--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2035ms
rtt min/avg/max/mdev = 0.033/0.056/0.090/0.025 ms

模拟之后ping测试延迟:

sh-4.2# sudo tc qdisc add dev lo root netem delay 1ms

sh-4.2# ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=2.04 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=2.04 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=2.17 ms
^C
--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 2.040/2.087/2.175/0.072 ms

ping包括数据发出去、收到回包两个动作,每个动作都引入了1ms的延迟,rtt增加2ms。

模拟千兆网卡

然后,如果loopback接口传输数据时希望有一定的网卡传输速率限制:

bash-4.2# sudo tc qdisc add dev lo root netem rate 1000mbit

然后你可以使用iperf来测试下是否真的是千兆网卡的传输速率,iperf起个server:

bash-4.2# iperf -s

然后再iperf起个client,观察二者的输出统计:

sh-4.2# iperf -c localhost
------------------------------------------------------------
Client connecting to localhost, TCP port 5001
TCP window size: 4.00 MByte (default)
------------------------------------------------------------
[  3] local 127.0.0.1 port 37004 connected with 127.0.0.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  1.16 GBytes   999 Mbits/sec

可以看到是999Mbit/sec,非常接近千兆网卡的传输速率了,全双工发送接受都是千兆。

模拟MTU

对了,正常TCP发包考虑到链路层封帧限制,还需要考虑mtu。

先看下lo默认的mtu设置是多少,65536,这个在真实网络中不会这么大的,比如eth0这个网卡对应的mtu只有1500:

sh-4.2# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc netem state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
...
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 0a:0b:0c:0d:0e:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0

好,现在来模拟下mtu等于1500:

sh-4.2# ip link set dev lo mtu 1500
sh-4.2# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 1500 qdisc netem state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到lo的mtu已经设置为1500了,这也会影响到后续的包的模拟发送接收。但是如果只是通过简单的ping localhost测试,是不会看出啥明显影响的。我们可能会预期mtu小了,难道帧多了上述增加的delay每个帧的延迟加起来不就变多了嘛?这跟delay工作的层次有关系,它是在网络层这层工作的。

也就意味着如果网络层的包,因为mtu比较小拆了很多分片出来,到达网络层后增加的延迟会明显增加的。这里暂时不用做到这么细,只需要关注网络层的整体请求、响应延迟即可。

同时模拟多种

当然,可以同时模拟多种行为,千兆网卡的传输速率限制+每次收发增加1ms传输延迟:

sh-4.2# ip link set dev lo mtu 1500
sh-4.2# sudo tc qdisc add dev lo root netem delay 1ms rate 1000mbit

重置模拟状态

当我们想重置对lo的修改时,就一切恢复到正常的默认状态了:

sh-4.2# sudo tc qdisc del dev lo root

本文小结

本文从个人开发角度、方便测试角度、还原网络“真实”情况角度出发,了解了下如何更好地利用lo网络模拟千兆网卡、网络传输延迟,实际测试下来比较符合预期,是一种本地开发过程中的有效手段。

本文主要是针对开发测试期间来考虑,要了解线上环境的最终测试情况,就是要做上线前压测、容量评估等工作。

两码事,都是应该做的,不过掌握了这个办法,本地1台开发机可以利用的有声有色。