尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

网络故障模拟实战:从tc/netem到坏网络模拟器

网络故障模拟实战:从tc/netem到坏网络模拟器 当你的接口在测试环境一切正常一上生产就超时、重试风暴、数据不一致时问题往往不在代码逻辑而在网络本身。分布式系统最怕的不是功能 Bug而是不可控的网络抖动、丢包和延迟。而绝大多数开发者在测试阶段根本不会主动制造这些故障直到线上事故把问题暴露出来。坏网络模拟器Bad Network Simulator就是为解决这个问题而生的。它能在本地或测试环境主动注入延迟、丢包、抖动、带宽限制等异常让你在故障真正发生之前就看到系统的真实反应。Bean Network Tester 正是这样一个开源方向的网络故障模拟工具。这篇文章会从原理讲起带你看懂坏网络模拟的核心机制手把手在 Linux 环境下跑通一次完整的网络故障注入实验并总结一套能直接用于日常开发测试的工程实践。读完本文你能理解网络故障模拟的底层原理掌握延迟、丢包、乱序等场景的模拟方法学会用脚本封装成可复用的故障测试工具并知道如何把这类工具安全地接入测试流程。1. 为什么需要“坏网络”模拟器很多团队测试分布式系统时默认网络是可靠的。联调环境在同机房带宽充足延迟稳定在 1ms 以内。结果就是熔断器没触发过、重试策略没验证过、超时时间拍脑袋定。一旦流量到了真实网络环境一个网络抖动就可能让整个链路雪崩。举一个典型场景。订单服务调用库存服务正常情况下耗时 50ms。某次发布后库存服务所在机器的网络出现瞬时丢包调用方设置的超时是 2 秒但 TCP 重传机制让这一次请求等了 4 秒。超时后订单服务抛出异常重试机制立刻补发请求库存服务此时已经出现线程池排队连续两次重试又加重了负载。几分钟内全链路超时订单大量失败。事后复盘发现如果测试环境能模拟一次“网络丢包 10%、持续 30 秒”问题在发布前就能暴露。这就是坏网络模拟器的价值它不是用来测功能正确性的而是用来验证系统在异常网络下的韧性。它能回答几个关键问题依赖服务慢到 3 秒才返回时你的服务会发生什么。网络丢包 20% 时你的重试机制是兜底还是帮倒忙。带宽被占满时你的连接池会不会先耗尽。网络故障恢复后系统能不能自动回到正常状态。从定位上看Bean Network Tester 这类开源坏网络模拟器要做的就是把“制造网络故障”这件事标准化、可配置、可重复。过去模拟坏网络需要手工敲 tc 命令或者用硬件网络损伤仪。现在用开源工具一条命令、一个配置就能注入指定强度的故障。这对中小团队尤其有用因为它把混沌工程里的“网络故障注入”这个能力从大厂的内部平台下沉到了普通开发者手里。我的判断是坏网络模拟器不应该只在故障演练时用它应该成为每个微服务项目测试环境的基础设施。你不需要像混沌工程平台那样做得很重但至少要有一套能随时制造延迟、丢包、断网的工具。2. 坏网络模拟的核心原理与常见手法要理解坏网络模拟器先要理解网络在什么情况下会“变坏”。从应用层的视角看网络故障可以拆成几种可量化的异常延迟Latency数据从发送到接收的时间变长。模拟方式通常是在数据包转发路径上增加额外等待时间。高延迟场景常见于跨地域调用、数据库慢查询引发的网络往返时间增加。丢包Packet Loss数据包在传输过程中被丢弃TCP 会启动重传UDP 则直接丢失数据。丢包对应用的影响远大于延迟因为它会导致请求变得不确定可能触发超时和重试。抖动Jitter延迟不稳定忽高忽低。视频通话卡顿、实时音视频质量差的根源多是抖动而非平均延迟高。对分布式系统来说高抖动会干扰超时时间设置和负载均衡的稳定性。乱序Reorder数据包到达顺序与发送顺序不一致。TCP 协议能处理一定程度的乱序但严重乱序会导致大量快速重传吞吐量骤降。带宽限制Bandwidth限速或拥塞导致吞吐量下降。常见于共享网络环境、云主机突发带宽用完的场景。损坏Corruption数据包内容被修改通常由链路层出错导致。TCP 校验和会发现错误并丢弃报文表现为丢包。在 Linux 环境下最常用的底层实现是内核自带的tc和netem模块。netemNetwork Emulator是内核提供的网络模拟模块可以挂载到某个网络接口的出口egress方向上对发出的数据包做延迟、丢包、乱序等处理。绝大多数据开源网络模拟工具底层最终都是通过修改tc规则或者使用更上层的 iptables、eBPF 等方式来实现故障注入。这里要先厘清一个容易混淆的概念网络代理Proxy和网络模拟Emulation的区别。像 Toxiproxy 这类工具工作在应用层它作为应用程序与目标服务之间的代理在转发过程中人为增加延迟或断开连接而 tc/netem 工作在内核协议栈的链路层附近直接作用于数据包。前者的好处是配置粒度细、支持按请求维度控制、不依赖 root 权限后者的好处是真实度更高、能影响所有经过该网卡的流量、不要求应用显式接入代理。Bean Network Tester 这类项目的通常做法是根据使用场景选择其中一种注入方式或者同时支持两种模式。这两种模式没有绝对的优劣真实项目中往往配合使用用代理模式做细粒度接口测试用内核模式做全链路混沌演练。3. 主流开源网络模拟工具对比在真实项目中选择哪类工具取决于你的测试目标和运行环境。工具工作层级使用方式适合场景tc/netem内核协议栈命令行配置网卡规则Linux 主机或容器最接近真实网络适合全链路故障注入Bean Network Tester同类开源工具以封装 tc/iptables 为主部分支持代理模式脚本或配置文件精确定义模拟规则日常测试环境快速制造网络故障重点是易用性和可重复性Toxiproxy应用层代理配置代理规则支持 HTTP/TCP 等协议接口测试、集成测试按请求维度精细控制Chaos Mesh 的 NetworkChaos云原生Kubernetes CRD 配置K8s 环境中对 Pod 注入网络故障Awsvf包装 tc 的上层工具命令行交互式操作界面友好适合临时手动测试Toxiproxy 是应用层坏网络模拟的代表。它的工作方式是启动一个本地代理进程被测服务把请求指向这个代理代理再将请求转发到真实目标服务。中间可以给转发链路加 latency、加 loss、设置带宽甚至直接断开连接。它的优势是故障注入粒度非常细可以只对某一个 upstream 加故障而 tc/netem 在主机层面不容易做到多租户隔离。缺点是应用必须走代理对已经写死直连地址的代码侵入性更强而且代理本身在高并发下可能成为性能瓶颈。Bean Network Tester 这类项目走的是另一条路线试图用较小的心智负担统一封装内核态和代理态的故障注入。从命名习惯来看“Bean”这个词借鉴了组件化、可装配的含义意味着它把网络故障抽象成一个个可组合的“豆子”模块。这个设计思路在工程上很有价值因为它把以前需要手写一连串 tc 命令的脏活变成声明式配置就像写单元测试那样描述“我要什么故障”而不是“我要怎么用 tc 造出这个故障”。工具不是越复杂越好。对大多数开发团队我建议先掌握 tc/netem 原生命令再用开源模拟器的封装。因为理解底层原理之后你用任何上层工具都能快速定位问题而不是在工具的抽象层里迷路。4. 环境准备与前置条件本文的实操部分以 Linux 环境为基础我会先演示用内核自带的 tc/netem 手动注入网络故障再演示如何封装成脚本。这套思路和 Bean Network Tester 类工具的内部实现一致你理解之后再去看任何开源网络模拟器的文档都会轻松许多。在进行下面的操作之前需要确认几件事。操作系统建议使用 Linux 发行版Ubuntu 20.04、Debian 10、CentOS 7 均可。Windows 用户建议通过虚拟机或 WSL2 体验但 WSL2 的网络栈比较特殊tc 规则可能不生效更推荐使用 Docker 容器。权限tc 操作网卡需要 root 权限。在本地测试机可以用 sudo 操作在服务器上要严格控制权限。任何情况下都建议先在专用的测试机上验证而不是直接在共享开发环境执行。内核模块tc 是内核自带功能netem 模块一般默认编译进内核。可以检查模块是否可用。# 检查 netem 模块是否可用 modprobe sch_netem echo $?如果输出 0说明模块可用。如果报错可能需要安装内核模块或确认内核配置。确认网卡名称ip addr show常见输出中物理机网卡可能是eth0、ens33虚拟机可能是ens160。本文示例统一使用eth0实际使用时请替换为自己的网卡名。如果你希望在不影响主机的场景下做实验推荐用 Docker 隔离出一个网络命名空间docker run -it --rm --name net-test --cap-add NET_ADMIN ubuntu:22.04 bash--cap-add NET_ADMIN是必须的否则容器内没有权限修改 tc 规则。这个选项只对容器内的网络命名空间生效不会影响 Docker 宿主机和其他容器是相对安全的实验方式。5. 核心流程拆解从手动注入到脚本封装坏网络模拟的完整流程可以拆成四个步骤确认目标网络接口、注入故障规则、验证故障效果、清理故障规则。每一步都有明确的判断标准。第一步是确认目标接口。如果要模拟“应用服务器到数据库服务器之间的网络”需要确认应用服务器访问数据库的出方向网卡。故障注入发生在出方向意味着会延迟、丢弃从这个网卡发出的数据包。第二步是注入故障规则。以 tc/netem 为例添加规则的基本语法是sudo tc qdisc add dev eth0 root netem delay 100ms这条命令的含义是在eth0的根队列root上挂载 netem 规则所有从eth0发出的数据包增加 100ms 延迟。这里有一个关键点tc qdisc add通常会失败如果你之前已经加过规则提示RTNETLINK answers: File exists需要先删除旧规则或使用change替换。第三步是验证故障效果。从另一台机器 ping 这台机器观察 RTT 是否出现预期延迟或者在目标机器上启动 HTTP 服务用 curl 测量请求耗时。如果延迟加了 100ms而 ping 结果没有变化说明规则挂错了接口或方向。第四步是清理规则。测试完成后必须删除规则否则测试机会持续处于坏网络状态。sudo tc qdisc del dev eth0 root在真实项目中这四步应该被封装成统一入口的脚本或工具而不是每次手动敲命令。Bean Network Tester 这类开源工具解决的就是这个痛点配置可复用、故障可重复、清理可自动完成。下面是几种常见的故障注入手法。延迟注入# 固定延迟 100ms sudo tc qdisc add dev eth0 root netem delay 100ms # 延迟 100ms 加上 20ms 的正态分布抖动 sudo tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal丢包注入# 固定丢包率 10% sudo tc qdisc add dev eth0 root netem loss 10% # 丢包率 10%并模拟 25% 的相关丢包更符合真实网络中的突发丢包 sudo tc qdisc add dev eth0 root netem loss 10% 25%乱序注入# 让 25% 的数据包延迟 50ms产生乱序效果 sudo tc qdisc add dev eth0 root netem delay 50ms reorder 25%带宽限制# 限制出口带宽为 1mbit sudo tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms注意多条故障可以叠加但 tc 的根队列只能有一个规则。更复杂的情形需要借助netem的limit、duplicate等参数或者使用中间队列设备ifb做入口方向的模拟。入口方向ingress的流量模拟比出口方向更复杂因为 tc 默认只处理出口方向需要借助 ifb 内核模块将入口流量重定向。对于大部分测试场景先掌握出口方向就足够用了。6. 完整示例坏网络注入脚本实现手动敲 tc 命令虽然灵活但不好维护。下面我提供一个可复用的坏网络注入脚本用纯 Bash 实现把延迟、丢包、抖动、乱序、带宽限制、损坏和清理统一封装起来。这个脚本在思路上模拟了 Bean Network Tester 类工具的最小核心逻辑你可以直接复制使用也可以基于它扩展。#!/usr/bin/env bash # badnet.sh - 一个可复用的坏网络注入脚本 # 用法示例: # ./badnet.sh delay eth0 100ms 20ms # ./badnet.sh loss eth0 10% 25% # ./badnet.sh reorder eth0 50ms 25% # ./badnet.sh rate eth0 1mbit # ./badnet.sh corrupt eth0 5% # ./badnet.sh clean eth0 # ./badnet.sh show eth0 set -euo pipefail ACTION${1:-show} DEV${2:-eth0} check_root() { if [[ $EUID -ne 0 ]]; then echo 错误请使用 sudo 运行此脚本 exit 1 fi } check_dev() { if ! ip link show $DEV /dev/null 21; then echo 错误网卡 $DEV 不存在 exit 1 fi } clean() { echo 清理 $DEV 上的 tc 规则 tc qdisc del dev $DEV root 2/dev/null || true echo 清理完成 } show() { echo 当前 $DEV 的 tc 规则 tc qdisc show dev $DEV } inject_delay() { local delay${3:-100ms} local jitter${4:-} check_root check_dev clean if [[ -n $jitter ]]; then echo 注入延迟: ${delay} 抖动: ${jitter} tc qdisc add dev $DEV root netem delay $delay $jitter distribution normal else echo 注入延迟: ${delay} tc qdisc add dev $DEV root netem delay $delay fi show } inject_loss() { local loss${3:-10%} local corr${4:-} check_root check_dev clean if [[ -n $corr ]]; then echo 注入丢包: ${loss} 相关概率: ${corr} tc qdisc add dev $DEV root netem loss $loss $corr else echo 注入丢包: ${loss} tc qdisc add dev $DEV root netem loss $loss fi show } inject_reorder() { local delay${3:-50ms} local reorder${4:-25%} check_root check_dev clean echo 注入乱序: 延迟 ${delay}, 乱序比例 ${reorder} tc qdisc add dev $DEV root netem delay $delay reorder $reorder show } inject_rate() { local rate${3:-1mbit} check_root check_dev clean echo 注入带宽限制: ${rate} tc qdisc add dev $DEV root tbf rate $rate burst 32kbit latency 400ms show } inject_corrupt() { local corrupt${3:-5%} check_root check_dev clean echo 注入数据损坏: ${corrupt} tc qdisc add dev $DEV root netem corrupt $corrupt show } case $ACTION in clean) check_root check_dev clean ;; show) check_dev show ;; delay) inject_delay $ ;; loss) inject_loss $ ;; reorder) inject_reorder $ ;; rate) inject_rate $ ;; corrupt) inject_corrupt $ ;; *) echo 未知操作: $ACTION echo 可用操作: clean | show | delay | loss | reorder | rate | corrupt echo 用法: echo $0 action [dev] [参数...] echo 示例: echo $0 delay eth0 100ms 20ms echo $0 loss eth0 10% echo $0 reorder eth0 50ms 25% echo $0 rate eth0 1mbit echo $0 corrupt eth0 5% echo $0 clean eth0 echo $0 show eth0 exit 1 ;; esac保存为badnet.sh然后赋予执行权限chmod x badnet.sh这个脚本的关键设计有四点第一条所有注入操作前先执行clean避免反复执行时出现File exists错误。这一点很重要因为 tc 的根队列规则只能存在一个反复 add 会直接报错陷入“命令看起来对了但执行失败”的困惑。第二条参数顺序固定为操作 网卡 故障参数。比如./badnet.sh delay eth0 100ms 20ms语义是“在 eth0 上注入 100ms 固定延迟和 20ms 抖动”。参数顺序统一便于在 CI 脚本和自动化测试中拼接。第三条show操作和clean操作分离。你可以在任何时刻查看当前注入状态避免测试结束后忘记清理。故障注入最怕的不是注入本身而是注入后没人负责清理导致测试环境长时间处于异常状态。第四条脚本前置函数有check_root和check_dev的防御性检查。网络模拟工具往往需要 root 权限而没有权限时的报错信息非常有误导性。提前检查能帮你省下大量排查时间。7. 运行结果与效果验证下面用一个实际实验来验证脚本是否生效。实验拓扑两台可以互通的 Linux 机器A 机器作为注入点B 机器作为目标。如果没有第二台机器也可以在 Docker 容器中对自身网卡注入用 curl 访问本机服务来观察效果。先用 ping 建立基线数据。在 B 机器上 ping A 机器的地址ping -c 5 192.168.1.10假设基线 RTTRound-Trip Time往返时延是 0.3ms 到 0.5ms。然后在 A 机器上执行延迟注入sudo ./badnet.sh delay eth0 100ms再次在 B 机器上 ping A 机器预期 RTT 会增加约 100ms变成 100.x ms 到 100.5ms。这里要注意ping 回应也走 A 机器的出口所以双向生效RTT 增加约 100ms 是合理的。接下来验证丢包。在 A 机器上执行sudo ./badnet.sh loss eth0 20%在 B 机器上 ping A 机器发送 20 个包预期能看到约 20% 的包丢失ping -c 20 192.168.1.10输出结果中查看x packets transmitted, y packets received, z% packet lossy 大约为 16z 约为 20%。如果只想验证脚本本身而不依赖第二台机器可以在一台机器上启动一个简单的 HTTP 服务然后对自身网卡注入故障再通过本机 IP 访问服务。例如# 终端 1启动一个简单的 HTTP 服务 python3 -m http.server 8080 # 终端 2注入延迟 sudo ./badnet.sh delay eth0 100ms # 终端 3测试访问耗时 time curl -s http://127.0.0.1:8080/ /dev/null注意访问127.0.0.1走的是 lo 回环接口不是 eth0所以要看效果需要使用本机的局域网 IP例如192.168.1.10或者把故障注入到lo接口。但向 lo 注入延迟会同时影响本机所有回环通信可能导致 SSH 等依赖网络的服务变慢实验后务必清理。更稳妥的做法还是用两台机器或者用 Docker 创建一个隔离网络。验证完效果后必须立即清理sudo ./badnet.sh clean eth0 sudo ./badnet.sh show eth0clean后tc qdisc show dev eth0应该不再显示 netem 或 tbf 规则。如果清理失败脚本内部的|| true会吞掉错误然后你可以手动检查规则残留tc qdisc show dev eth0对于应用层验证更接近分布式系统真实体感的方式是用 curl 观察业务接口耗时。假设被测服务返回 JSON 字符串用时没有故障时是 50ms注入 200ms 延迟后耗时应该增加到约 250ms。如果业务代码里有超时和重试逻辑此时就能直观看到重试次数是否增加超时时间是否设置得合理。8. 常见问题与排查思路网络模拟因为涉及内核网络栈出错时的表象往往不是“规则没加上”而是“规则加了但没效果”或“效果远超预期”。下面梳理几个高频问题。问题现象可能原因排查方式解决方案tc qdisc add 报 File exists根队列已存在规则执行 tc qdisc show dev eth0 查看现有规则先删除旧规则或直接使用脚本中的 clean 功能延迟注入后 ping 无变化规则加错了网卡或只对 egress 生效确认流量实际经过的网卡检查 ping 目标地址属于哪个网卡改用正确的网卡名确认测试流量经过该网卡延迟注入后 curl 本机地址无变化本机回环地址走 lo 接口不受 eth0 规则影响使用局域网 IP 或把规则加到 lo 接口使用 ip addr 查看本机局域网 IP或在 Docker 隔离网络内测试容器内无法执行 tc容器缺少 NET_ADMIN 权限检查 docker run 是否加了 --cap-add NET_ADMIN重新以 --cap-add NET_ADMIN 启动容器注入丢包比例远高于预期丢包百分比解释可能与预期不同相关丢包参数造成突发丢包用小比例如 1%实验并观察统计结果先不加相关概率参数观察基础丢包率是否符合预期故障清理后网络仍然异常还有其他 qdisc 规则残留或 iptables 有额外规则全面检查 tc qdisc show 和 iptables -L逐个删除残留规则重启网络服务或容器恢复干净状态规则注入生效但影响范围太大没有限定目标 IP规则作用于整个网卡的出口流量检查业务机器是否被误伤用 iptables 配合 tc 的 prio 或 flower 过滤器按目标 IP 精确限流这里重点说两个细节。第一个是关于tc只对出口方向生效的问题。tc 的 netem 默认挂载在根队列上处理的是从网卡发出的数据包。如果你想让“进入本机”的流量也变慢需要借助 ifb 设备把入口流量重定向到 tc 规则上。对于大多数联调场景在接收方注入出口延迟已经足够模拟“网络慢”因为 TCP 是双向通信任何一方的出口变慢都会造成整条链路变慢。第二个是“影响范围太大”的问题。默认的tc qdisc add dev eth0 root netem会影响所有来自 eth0 的流量这在共享开发机上是危险的。更安全的方式是配合 iptables 按目标端口或目标 IP 做过滤。常见做法是使用htb或prio队列分类再在内层附加 netem。这里涉及较复杂 qdisc 层级建议先在专用测试机上验证再决定是否在共享环境使用。9. 在测试环境接入坏网络模拟的工程建议搞清楚了原理和脚本最后讨论如何在真实项目中用好坏网络模拟。第一从最小的故障场景开始不要一上来就搞全链路混沌。先选定一个核心链路比如“用户服务调用订单服务”注入 10% 丢包和 200ms 延迟观察 10 分钟内的错误率、超时数、重试次数。输出一份简单的报告记录“故障参数 - 系统行为 - 是否触发熔断 - 恢复时间”。做好这个小场景再逐步扩大范围。第二把网络模拟接入持续集成流程。CI 里跑集成测试时可以启动一个并行任务专门对被测服务的某个依赖注入延迟。这能最早发现超时设置不合理的问题。一个可落地的做法是在 test 阶段的 docker-compose 文件中增加一个网络模拟容器通过 iptables 或 tc 对指定的容器网络接口注入故障。Bean Network Tester 这类工具如果支持配置文件驱动完全可以放置到 CI 的 workflow 目录里由流水线自动执行。第三配置要版本化、可追溯。不要把故障参数写死在 shell 命令里。建议用 YAML 或 JSON 描述故障场景# network-fault.yaml scenario: auth-service-delay description: 模拟认证服务网络延迟 300ms target_service: auth-service faults: - type: delay device: eth0 delay: 300ms jitter: 50ms - type: loss device: eth0 loss: 5% duration: 60s cleanup: always这样的配置文件放到代码仓库里和业务代码一起评审、一起回溯。任何团队成员都能看懂“这次故障演练到底模拟了什么”而不是看一堆难以记忆的 tc 命令。开源工具通常会在配置解析和场景编排上做更多这也是你在选择工具时值得关注的维度它能否从 YAML 配置直接生成并清理故障而不是回到你手写脚本。第四故障演练前必须做安全评估。网络故障模拟在生产环境带来的风险是真实存在的。任何开源的坏网络模拟器都不应该未经团队评审就用于生产。生产环境的故障演练需要专门的权限审批、灰度方案和回滚机制测试环境也要注意注入规则可能影响局域网内的其他机器。建议的边界是共享开发机只使用按端口或按目标 IP 的精确注入Docker 网络内的容器之间可以更大胆地做全链路模拟生产环境必须有独立的混沌演练平台和完整的告警监控。第五注意超时、重试和熔断之间的相互影响。坏网络模拟最大的价值是暴露这三者配合不当的问题。实际测试时不要只关注接口是否报错要关注调用链路的熔断器状态、线程池活跃度、重试造成的流量放大倍数。这些都是分布式系统韧性的核心指标。没有监控数据的坏网络模拟只能证明“系统会出错”不能证明“系统的容错设计是否有效”。10. 总结与后续学习方向坏网络模拟器是分布式系统测试中价值密度很高的基础工具。围绕着它你需要掌握的核心能力包括理解延迟、丢包、抖动、乱序、带宽限制这几种网络故障的量化含义掌握 tc/netem 的基本用法重点是规则挂载、规则叠加和规则清理能把故障注入封装成脚本或配置文件进入 CI 流程能结合监控数据判断系统的容错设计是否真的有效。Bean Network Tester 和同类开源项目给开发者带来的真正价值是把过去只有专业网络工程师才能熟练操作的 tc 规则封装成普通人也能理解、使用和复用的工具。但无论上层工具怎样简化底层的网络原理依旧逃不开。所以我建议你花一个下午把文章里的脚本跑一遍亲手制造一次延迟和丢包再用tc qdisc show观察规则变化。这个过程能帮你建立对网络模拟最直接的感觉。接下来你可以继续深入的方向是学习用 ifb 做入口方向流量模拟解决双向网络故障注入问题研究 Toxiproxy 这类应用层代理工具的 API把它集成进单元测试和集成测试中如果团队使用 Kubernetes可以研究 NetworkChaos 的 CRD 定义在集群维度管理网络故障更进一步可以把网络模拟和 Chaos Mesh、Litmus 等混沌工程平台结合设计完整的故障演练计划。网络故障不会因为你不模拟它就不存在。与其等到线上告警来通知你系统的脆弱点不如现在主动制造一次故障看看你的系统会怎样应对。
返回列表