网络层面的混沌工程

以下内容来自与Gemini的对话后,Gemini的回答

你想要做的这个Monkey测试(混沌工程)——即模拟系统互联抖动(Jitter)、丢包、异常,来验证数据完整性(Data Consistency/Integrity),这正是分布式系统中最核心、最难测试的部分。

虽然 bpftrace 做这个比较吃力,但 Linux 内核自带了一套神器,专门用来做这件事。它不需要你写代码,只需要敲几行命令,就能精准模拟各种“烂网络”。

这个神器叫做 tc (Traffic Control) 配合 netem (Network Emulator)

我来教你如何用它们构建一个**“数据完整性地狱”**,来看看你的后端代码能不能扛得住。

核心武器:TC + Netem

tc 是 Linux 内核网络栈自带的流量控制器。它可以工作在网卡(Network Interface)的出口,对数据包进行排队、整形、延迟、丢弃。

不需要安装任何软件,你的 Rocky Linux 里就有。

场景一:模拟“网络抖动” (Network Jitter)

测试目标: 验证后端是否有超时重试机制?重试会不会导致数据重复插入(幂等性问题)?

命令:

Bash

# 在 eth0 网卡上,添加 100ms 的延迟,并带有 +/- 20ms 的随机抖动
# 且遵循正态分布 (distribution normal)
sudo tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal

效果:

场景二:模拟“随机丢包” (Packet Loss)

测试目标: 验证 TCP 断连后的事务回滚(Transaction Rollback)是否正常?

命令:

Bash

# 随机丢弃 10% 的数据包
sudo tc qdisc add dev eth0 root netem loss 10%

效果:

场景三:模拟“包损坏”与“乱序” (Corruption & Reordering)

测试目标: 验证应用层协议的校验能力。

命令:

Bash

# 随机让 5% 的包发生比特翻转(损坏),让 25% 的包不按顺序到达
sudo tc qdisc add dev eth0 root netem corrupt 5% reorder 25%

进阶:如何只搞“数据库”,不搞“SSH”?

直接在 eth0 上搞 netem 会影响所有流量,把你自己的 SSH 也就搞卡了。我们需要精准打击

这就需要用到 tc filter 或者更简单的 IFB (Intermediate Functional Block) 设备,但为了简单,我推荐一个更好用的封装工具:comcast 或者 pumba(如果你用 Docker)。

但如果你想手动用原生命令,可以配合 cgroup 或者端口过滤。这里有一个简单的端口级故障注入流程:

目标:只干扰连接 MySQL (3306) 的流量,模拟写入延迟。

Bash

# 1. 创建一个优先队列 (PRIO)
sudo tc qdisc add dev eth0 root handle 1: prio

# 2. 在第 1 个子队列上应用 500ms 延迟 (这就是我们要的故障)
sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 500ms

# 3. 设置过滤器:凡是发往 3306 端口的包,扔到第 1 个子队列(故障队列)
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 3306 0xffff flowid 1:1

# 4. 其他流量默认走第 2/3 队列 (不受影响)

架构师视角:如何设计“数据完整性”验证实验?

有了上面的工具,你就可以设计实验了。单纯的“卡”没有意义,你需要观测数据。

实验设计模板:

  1. 基准状态 (Baseline):
    • 后端是一个简单的转账接口:A -> B 转 100 元。
    • 编写一个脚本,并发跑 1000 次转账。
    • 预期: A 减了 100000,B 加了 100000。
  2. 注入故障 (Chaos Injection):
    • 使用 tc 命令,设置 30% 丢包 + 200ms 延迟
    • 开启故障。
  3. 运行负载 (Run Workload):
    • 再次运行那 1000 次转账脚本。
    • 你会看到客户端报很多 Timeout Exception 或 Connection Reset。
  4. 验证一致性 (Verify Consistency):
    • 这是最关键的一步。
    • 等待所有请求结束(包括重试)。
    • 查询数据库:
      • 情况 A (完美): A 减去的金额 == B 增加的金额。
      • 情况 B (数据丢失): A 减了钱,但 B 没收到(丢包导致事务提交了一半?)。
      • 情况 C (数据重复): B 收到的钱比 A 减去的还多(超时重试导致重复入账)。

推荐工具:Shopify 的 Toxiproxy

如果你觉得 Linux 的 tc 命令太晦涩,太容易把机器搞断网。我强烈推荐你使用 Shopify 开源的 Toxiproxy

总结:
要测试系统互联抖动对数据的影响:

  1. 底层派: 用 Linux 原生 tc + netem。真实、硬核、能模拟 TCP 协议栈级别的故障。
  2. 应用派: 用 Toxiproxy。简单、安全、易于集成到 CI/CD 流水线。

这才是真正的“后端内功”修炼。如果你的系统能在 tc qdisc add … loss 30% 的情况下依然保持账目平齐,那就是真正的高可用系统。

| 访问量:
Table of Contents