Skip to content

用 nsim 造出真实世界的坏网络

性能那一篇反复强调:本环境不能测性能。 这一篇不推翻那个结论,而是补上另一半 ——

本环境可以造出真实的网络损伤,从而观察那些在理想链路上根本看不到的现象。

实验环境的另一个偏差

我们一直在说 AF_PACKET 让性能数字不可信。但还有一个方向的偏差, 之前没提过:这套链路太好了。

text
  本实验环境      RTT 0.09 ms,零丢包
  同城机房之间     RTT 1~3 ms
  跨城           RTT 20~40 ms
  跨洲           RTT 150~300 ms
  移动网络        RTT 30~100 ms,丢包 0.1%~2%

理想链路会掩盖很多真实问题。TCP 在零丢包零时延下跑得飞快, 你看不出窗口、重传、拥塞控制在真实网络里造成的差异。

nsim(Network Delay Simulator)插件能把这些补回来。

配置

bash
# 三个参数都是必需的
set nsim delay <> bandwidth <> packet-size <>
    [packets-per-drop <n>] [drop-fraction <0.0-1.0>]

# 挂到接口
nsim output-feature enable-disable <>

show nsim

应用配置

bash
./labctl reset base
./labctl apply base 17
./labctl verify base 17
bash
vppctl set nsim delay 20ms bandwidth 1000mbps packet-size 1500
vppctl nsim output-feature enable-disable host-eth2

两个容易踩的坑

一、enable-disable 是开关切换,不是"启用"。

执行两次等于又关掉了。写幂等脚本时必须先查状态:

bash
if ! vppctl show interface features host-eth2 | tr -d '\r' | grep -q nsim; then
  vppctl nsim output-feature enable-disable host-eth2
fi

我第一次调试时连按两次,然后花了不少时间纳闷"为什么配了没效果"。

二、它挂在 interface-output 弧上,不是 ip4-output

bash
vppctl show interface features host-eth2
text
ip4-output:
  none configured          ← 在这儿找不到

interface-output:
  nsim-output-feature      ← 在这儿

ip4-output 里找 nsim 会以为没挂上。

时延注入:精度很好

text
  配置时延   实测 RTT
  ────────  ────────────────────────────────────
  0.1ms     round-trip min/avg/max = 0.172/0.215/0.312 ms
  20ms      round-trip min/avg/max = 20.101/20.117/20.230 ms
  50ms      round-trip min/avg/max = 50.103/50.123/50.233 ms

几乎是精确相加(基线约 0.1~0.2ms),抖动也很小。

丢包注入

text
  配置 drop-fraction   实测丢包率(40 个 ping)
  ──────────────────  ──────────────────────
  0                   0% packet loss
  0.1                 10% packet loss
  0.3                 42% packet loss

比例基本吻合,样本小的时候会有偏差(40 个包的采样误差本来就大)。

这才是重点:TCP 吞吐的真实代价

ping 只能看到时延和丢包本身。真正有价值的是看它们对应用的影响。 实验用一个 2MB 的 TCP 传输来测:

text
  时延      丢包    TCP 吞吐
  ────────  ──────  ──────────────────────────────
  0.1ms     0       365.0 Mbps
  20ms      0       118.7 Mbps
  50ms      0        28.7 Mbps
  20ms      0.02      4.2 Mbps      ← 只加了 2% 丢包

两个结论,都是理想链路上看不到的。

一、光是时延就能压垮吞吐

从 0.1ms 到 50ms,吞吐掉了 92%,而链路带宽一个字节都没变。

原因是带宽时延积(BDP):TCP 在等到确认之前最多能发一个窗口的数据, 所以吞吐上限约等于 窗口大小 / RTT。RTT 涨十倍,吞吐掉十倍 —— 和链路有多宽无关。

这是"我买了千兆带宽但下载国外文件只有几 Mbps"的经典成因。

二、2% 丢包的代价远不止 2%

20ms RTT 下,从零丢包加到 2%,吞吐从 118.7 掉到 4.2 Mbps —— 掉了 96%

TCP 的吞吐大致与丢包率的平方根成反比(Mathis 公式)。 2% 的丢包不是"损失 2% 的数据",而是让拥塞窗口反复被砍半, 永远涨不上去。

这条结论在排障时很有用

运维口中的"链路只丢了 2% 的包,应该没什么影响"是个非常常见的误判。

反过来说:用户报告"网速慢"而带宽监控显示远未饱和时, 先查丢包,而不是加带宽。加带宽对丢包引起的慢完全无效。

它如何改变第 7 章的性能结论

性能那一篇量过 NAT 的处理开销:

text
  快路径   615 clocks/包
  慢路径   8450 clocks/包(约 3.7 微秒 @ 2.3GHz)

放到有真实时延的网络里对比:

text
  NAT 慢路径开销    ≈ 0.0037 ms
  一次跨城 RTT      ≈ 20 ms
  占比              ≈ 0.02%

在有真实时延的网络里,NAT 的处理开销根本不是瓶颈。

这不是说 NAT 性能不重要 —— 它在高并发新建会话时确实是瓶颈 (第 7 章测过 CPS 场景下吞吐掉到 27%)。但对单个用户的体验来说:

text
  优化 NAT 的微秒级开销        →  用户完全感知不到
  把丢包从 2% 降到 0           →  吞吐涨 28 倍

优化的优先级一目了然。

本环境现在能做和不能做的

nsim 补上了一块,但边界还是要说清:

text
  ✓ 现在能做
  ────────────────────────────────────────────────
  造出可控的时延、抖动、丢包
  观察 TCP 在真实网络条件下的行为
  验证"丢包比时延更致命"这类结论
  测试应用在弱网下的表现
  给 policer 的突发桶配置提供真实 RTT 参考

  ✗ 仍然不能做
  ────────────────────────────────────────────────
  任何绝对性能数字(AF_PACKET 的瓶颈没变)
  高 pps 下的转发能力
  多 worker 的扩展性

nsim 改善的是网络条件的真实性,不是转发路径的真实性。 两者是独立的偏差,它只解决了后一个之外的那一个。

其他可用参数

text
  bandwidth <bps>        带宽上限,超出会排队(配合 delay 模拟拥塞)
  packet-size <字节>      用于计算队列深度,按典型报文大小给
  packets-per-drop <n>    每 n 个包丢一个(确定性丢包,便于复现)
  drop-fraction <f>       按比例随机丢包(更接近真实)

packets-per-dropdrop-fraction 的区别值得一提: 前者是确定性的,适合做可复现的回归测试; 后者是随机的,更像真实网络。调试具体问题时用前者, 评估整体表现时用后者。

小结

解决什么实验环境链路"太好",掩盖真实网络下的行为
配置set nsim delay X bandwidth Y packet-size Z [drop-fraction F]
挂载nsim output-feature enable-disable <接口>是开关不是启用
位置interface-output 弧,不在 ip4-output
时延精度很好,几乎精确相加
关键发现一时延从 0.1ms 到 50ms,TCP 吞吐掉 92%
关键发现二2% 丢包让吞吐掉 96% —— 远不止 2%
对性能章的意义真实 RTT 下 NAT 开销占 0.02%,不是瓶颈
边界只改善网络条件的真实性,转发路径的偏差依然存在

实验环境基于 netlab + containerlab + VPP 26.06