我想研究从慢速服务器流式传输的应用程序的行为。我试图利用tc-netem
引入网络延迟。
在设置更复杂的场景之前,我决定在虚拟机上执行此操作,该虚拟机应该模拟慢速服务器。我通过访问虚拟机ssh
,所以我决定创建一个虚拟以太网,这会延迟,而我计划使用真实的以太网设备进行管理。
首先,我创建了假接口ip link add link eth0 type macvtap
并为其分配了 IP 地址。
然后我添加了 40 毫秒的延迟tc qdisc add dev macvtap0 root netem delay 40000
。这实际上让我的吞吐量下降了(从 ~250 MiB/秒到 ~6 MiB/秒)。
此时,我尝试稍微调整一下我的设置,然后我开始意识到延迟不仅影响设备macvtap0
,而且还影响eth0
我所连接的设备(简而言之,我的ssh
会话开始滞后)。
我认为我netem delay
影响了实际的网卡。这是因为我在虚拟机中工作吗?或者我应该使用不同的棕褐色macvtap
?或者可能是因为我将更改应用到了root qdisc
?
编辑- 这是我第一次进入看似巨大的流量差异化世界。也许有更好的方法?例如,我可以设置一个队列来减慢选定的进程吗?我决定重新命名这个问题以反映我的实际目的。
答案1
首先说明一下:增加延迟与限制带宽不同。考虑地球同步卫星互联网链接:单向流有约 1/4 秒的强制性延迟(由于光速),因此如果整个路径通过卫星传输,往返可能为约 1/2 秒,并且它是说成为能够达到 506 Mbps使用现代技术:大量数据可以在这个 1/2 秒的窗口中传输,无需等待每个数据包的确认后再发送下一个数据包。当然,延迟对速度没有任何帮助,而且可能会因为等待确认、需要重传等而阻碍速度。
由于提出问题的问题和问题的目标是真的不同的是,除了这些信息之外,我只会回答以下问题。
一些 qdisc 具有内置的速率限制功能:HTB,TBF,...这里有两个关于限制带宽(而不是增加延迟)的建议:
-
# tc qdisc add dev eth0 root tbf rate 1024kbit latency 50ms burst 1540
请注意,与往常一样,限制是针对出口的。为了限制进入,IFB必须插入设备,如我的回答中的示例使用netem模拟桥接接口上的丢包。
好(不是那么旧)
wondershaper
脚本(v1.4。它在某些发行版(如 Debian)中已经过时),它可以创造奇迹:虽然设计用于优先考虑流并降低延迟,但它也可以降低速率,并且已经使用 IFB 以简单的方式进行限制出口和入口。# wondershaper -a eth0 -d 1000 -u 100
会将eth0
的带宽限制为 1000 kbps 下载和 100 kbps 上传。
现在关于这个问题...
该问题与以下内容无关macvtap
(该tap
部分甚至没有在OP的设置中使用),也不macvlan
也没有任何虚拟化也没有tc-netem
。它与使用同一 IP LAN 将多个接口置于同一以太网 LAN 中时路由的工作方式有关。
由于如果没有 OP 在虚拟机中的特定配置,就无法确定发生了什么,因此我将在几个网络命名空间中重现一个人为示例:“system”同行ping“系统”双卡,两者都通过“开关”链接桥。
添加第二张卡之前的初始配置:
ip netns del bridge || :
ip netns del twocards || :
ip netns del peer || :
ip netns add bridge
ip netns add twocards
ip netns add peer
ip -n bridge link add bridge0 type bridge
ip -n twocards link add eth0 type veth peer netns bridge name port1
ip -n peer link add eth0 type veth peer netns bridge name port2
ip -n bridge link set port1 master bridge0
ip -n bridge link set port2 master bridge0
ip -n bridge link set port1 up
ip -n bridge link set port2 up
ip -n bridge link set bridge0 up
ip -n twocards link set eth0 up
ip -n peer link set eth0 up
ip -n twocards address add dev eth0 192.0.2.1/24
ip -n peer address add dev eth0 192.0.2.2/24
现在:
# ip -n twocards route
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.1
在使用无处不在的 NetworkManager 的典型安装中,会有一metric 100
组以太网设备,让我们做同样的事情:
ip -n twocards route add 192.0.2.0/24 dev eth0 src 192.0.2.1 metric 100
ip -n twocards route del 192.0.2.0/24 dev eth0 src 192.0.2.1
我们来测量一下:
# ip netns exec peer ping -c2 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.116 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=0.060 ms
--- 192.0.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1018ms
rtt min/avg/max/mdev = 0.060/0.088/0.116/0.028 ms
结果正常。添加第二张卡,为其添加 IP 并添加 netem 队列:
ip -n twocards link add eth1 type veth peer netns bridge name port3
ip -n bridge link set port3 master bridge0
ip -n bridge link set port3 up
ip -n twocards link set eth1 up
ip -n twocards address add dev eth1 192.0.2.3/24
ip netns exec twocards tc qdisc add dev eth1 root netem delay 40000
新路线:
# ip -n twocards route
192.0.2.0/24 dev eth1 proto kernel scope link src 192.0.2.3
192.0.2.0/24 dev eth0 scope link src 192.0.2.1 metric 100
新行为(假设继承rp_filter
已设置):
# ip netns exec peer ping -c2 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
--- 192.0.2.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1021ms
发生了什么?现在路由和 ARP 行为开始发挥作用:
# ip -n twocards route get 192.0.2.2 from 192.0.2.1
192.0.2.2 from 192.0.2.1 dev eth1 uid 0
cache
# ip -n twocards -br link
lo DOWN 00:00:00:00:00:00 <LOOPBACK>
eth0@if3 UP 96:45:4d:f0:52:35 <BROADCAST,MULTICAST,UP,LOWER_UP>
eth1@if5 UP c2:70:b7:40:6c:40 <BROADCAST,MULTICAST,UP,LOWER_UP>
# ip -n peer neighbour
192.0.2.1 dev eth0 lladdr 96:45:4d:f0:52:35 REACHABLE
上的路由表双卡现在会使用eth1
,甚至对于分配给 的地址eth0
。 Linux 只是遵循其路由表的默认行为。因为rp_filter
启动后,设备eth0
(其 MAC 仍在同行的缓存)。如果rp_filter
没有设置,这将适用于非对称路由:在 上 ping 请求eth0
,在 上 ping 回复eth1
,(延迟netem
)直到同行的 ARP 缓存最终过期,然后eth1
仅使用(仅出口像往常一样延迟)。
让我们清除 ARP 缓存同行然后再试一次:
# ip -n peer neighbour flush dev eth0
# ip netns exec peer ping -c2 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=80.2 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=40.1 ms
--- 192.0.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 40.141/60.178/80.215/20.037 ms
# ip -n peer neighbour
192.0.2.1 dev eth0 lladdr c2:70:b7:40:6c:40 REACHABLE
第一个 ping(仅)被 netem 延迟两次:一次用于底层 ARP 回复 ARP 请求,一次用于实际 ping 回复。
让我们删除额外设备的路由双卡并再次清除 ARP 缓存同行:
ip -n twocards route del 192.0.2.0/24 dev eth1
ip -n peer neighbour flush dev eth0
再次正常结果:
# ip netns exec peer ping -c2 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=0.050 ms
--- 192.0.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.050/0.079/0.108/0.029 ms
同样 ping 分配给的 IPeth1
现在也会通过双卡毫不eth0
拖延:
# ip netns exec peer ping -c2 192.0.2.3
PING 192.0.2.3 (192.0.2.3) 56(84) bytes of data.
64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.143 ms
64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.042 ms
--- 192.0.2.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.042/0.092/0.143/0.051 ms
那么对此应该怎么办呢?只是不要在同一系统上使用同一以太网 LAN 上的两个网络设备,尤其是在使用同一 IP LAN 时,这会导致麻烦。macvlan
或设备macvtap
通常不应该由主机直接使用:它应该被移交给具有自己独立路由堆栈的虚拟机或容器(另一个网络命名空间),因此这不会成为问题一个典型的用法。
如果出于某种原因必须使用同一 LAN 上的两张卡(除了绑定、分组等之外),则必须进行额外的相当复杂的配置来避免这种情况。请参阅我在 SF 上的回答多 NIC Linux 系统上的 Ghost ping了解详情。
答案2
我不确定你遇到的问题,所以我跳过它。
如果您想调整每个进程的流量整形,您将需要使用有类排队规则。 HTB 或 HSFC 可能是您最好的选择。使用它,您可以创建一棵排队规则树(netem 可以附加到其中一个叶子)并使用 分配它们之间的流量tc filter
。
过滤非常灵活,因为fw
过滤方法可以查找 iptables 标记,这意味着您可以使用 iptables 选择流量。您也可以直接选择流量。
话虽如此,请注意 qdisc 仅对传出流量有效。您可以拥有一个入口 qdisc,但这非常有限,并且可能不会按照您的预期运行。
出于测试目的,一个不错的选择是创建一个具有两个接口的真实虚拟机,并以某种方式强制通过该虚拟机路由流量。可能需要一些技巧(即几个级别的 NAT)。然后,在虚拟机中,您可以在两个接口上附加您喜欢的任何 qdisc,从而控制流量的两个方向。