首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

看我如何作死 | 网络延迟、网络丢包、网络中断一个都没落下过

  • 25-03-02 17:22
  • 4359
  • 13935
blog.csdn.net

点击上方“朱小厮的博客”,选择“设为星标”

回复”1024“获取独家整理的学习资料

欢迎跳转到本文的原文链接:https://honeypps.com/chaos/how-to-simulate-network-fault/

 

昨天,笔者讲述了如何将CPU和IO撑满,这个其实很好理解,写个CPU密集型的程序让CPU忙个不停就可以撑满CPU;弄个程序一直写就可以让IO也撑满。有兴趣的同学可以看下昨天的这篇文章《看我如何作死 | 将CPU、IO撑满》,不过里面的做法分别是使用openssl speed和linux dd工具来实现这两个功能。

面对CPU和IO时,相信大家都能很快的反应出如何实现,那么面对网络问题时,大家的反应又是如何呢?不会是拔网线吧。。。

在故障注入,或者说故障演练,甚至说混沌工程中,可以设计很多类型的故障,今天要介绍的就是网络故障。

混沌系统是在分布式系统上进行实验的学科,目的是建立对系统抵御生产环境中失控条件的能力以及信心。

在复杂的网络环境下,数据包发送和接收的时间间隔或长或短。在网络状况较差时,调用下游服务时可能要过很久才能收到返回,这时服务的反应如何,直接关系到稳定性与高可用。

我们这里索要模拟的网络故障有三类,分别是:网络延时、网络中断以及网络丢包。

一、tc工具介绍

笔者也不卖关子,本文模拟的网络故障是通过linux的tc工具来实现的。Linux内核网络协议栈从2.2.x开始,就实现了对服务质量的支持模块。具体的代码位于net/sched/目录。在Linux里面,对这个功能模块的称呼是Traffic Control ,简称TC。TC是一个在上层协议处添加Qos功能的工具,原理上看,它实质是专门供用户利用内核Qos调度模块去定制Qos的中间件。

Linux操作系统中的流量控制器TC(Traffic Control)用于Linux内核的流量控制,主要是通过在输出端口处建立一个队列来实现流量控制。

640?wx_fmt=png

接收包从输入接口(Input Interface)进来后,经过流量限制(Ingress Policing)丢弃不符合规定的数据包,由输入多路分配器(Input De-Multiplexing)进行判断选择:如果接收包的目的是本主机,那么将该包送给上层处理;否则需要进行转发,将接收包交到转发块(Forwarding Block)处理。转发块同时也接收本主机上层(TCP、UDP等)产生的包。转发块通过查看路由表,决定所处理包的下一跳。然后,对包进行排列以便将它们传送到输出接口(Output Interface)。一般我们只能限制网卡发送的数据包,不能限制网卡接收的数据包,所以我们可以通过改变发送次序来控制传输速率。Linux流量控制主要是在输出接口排列时进行处理和实现的。

tc工具的语法还是很复杂的,笔者(微信公众号:朱小厮的博客)试图想要在本文中详细的讲解一下tc的用法,最后还是放弃了,篇幅太长,难以穷尽。所以本文中只是针对前面说的三种故障简单的演示一下tc的用法以及对应故障的实现方式,希望能够能大家有个小小的印象。如果以后遇到类似问题,或者说对这个东西感兴趣,可以再深度的学习一下。

二、paping工具介绍

在正式介绍如何模拟网络故障之前,还要介绍一个工具来查看模拟的效果如何。

通常我们测试数据包能否通过IP协议到达特定主机,都习惯使用Ping命令,工作时发送一个ICMP Echo,等待接受Echo响应,但是Ping使用的是ICMP协议,如果防火墙放通了此协议,依旧能够ping通,但是无法确定通过tcp传送的数据包是否正常到达对端。

而paping可以在Linux平台上测试网络的连通性及网络延时等。它的用法很简单:

  1. -p, --port N 指定被测试服务的 TCP 端口(必须);
  2. --nocolor 屏蔽彩色输出;
  3. -t, --timeout 指定超时时长,单位为毫秒,默认值为 1000;
  4. -c, --count N 指定测试次数。

比如下面的示例(记得先要开启一个以80为端口的服务, 示例中的xxx.xxx.xxx.xxx代表ip地址):

  1. hidden@hidden$ ./paping -p 80 -c 5 xxx.xxx.xxx.xxx
  2. paping v1.5.5 - Copyright (c) 2011 Mike Lovell
  3. Connecting to xxx.xxx.xxx.xxx on TCP 80:
  4. Connected to xxx.xxx.xxx.xxx: time=27.47ms protocol=TCP port=80
  5. Connected to xxx.xxx.xxx.xxx: time=97.83ms protocol=TCP port=80
  6. Connected to xxx.xxx.xxx.xxx: time=37.38ms protocol=TCP port=80
  7. Connected to xxx.xxx.xxx.xxx: time=57.62ms protocol=TCP port=80
  8. Connected to xxx.xxx.xxx.xxx: time=71.87ms protocol=TCP port=80
  9. Connection statistics:
  10.     Attempted = 5, Connected = 5, Failed = 0 (0.00%)
  11. Approximate connection times:
  12.     Minimum = 27.47ms, Maximum = 97.83ms, Average = 58.43ms

可以看到平均链接时间为58.43ms。

如果你的机器上没有安装paping,那么可以采用如下的方式安装:

  1. wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/paping/paping_1.5.5_x86_linux.tar.gz
  2. tar -zvxf paping_1.5.5_x86_linux.tar.gz
  3.  ./paping -p 80 -c 5000 www.baidu.com

如果有以下的错误:

./paping: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

可以先安装对应的库来解决:

  1. sudo apt-get install libstdc++6
  2. sudo apt-get install lib32stdc++6

三、模拟网络延时

使用tc命令模拟延迟300ms(对应的删除命令为tc qdisc del dev eth0 root netem):

  1.  tc qdisc add dev eth0 root netem delay 300ms
  2. // 该命令将网卡eth0的传输设置为延迟300ms发送

此时再次执行paping命令:

  1. hidden@hidden$ ./paping -p 80 -c 5 xxx.xxx.xxx.xxx
  2. paping v1.5.5 - Copyright (c) 2011 Mike Lovell
  3. Connecting to xxx.xxx.xxx.xxx on TCP 80:
  4. Connected to xxx.xxx.xxx.xxx : time=326.11ms protocol=TCP port=80
  5. Connected to xxx.xxx.xxx.xxx : time=417.02ms protocol=TCP port=80
  6. Connected to xxx.xxx.xxx.xxx : time=326.94ms protocol=TCP port=80
  7. Connected to xxx.xxx.xxx.xxx : time=326.19ms protocol=TCP port=80
  8. Connected to xxx.xxx.xxx.xxx : time=353.51ms protocol=TCP port=80
  9. Connection statistics:
  10.     Attempted = 5, Connected = 5, Failed = 0 (0.00%)
  11. Approximate connection times:
  12.     Minimum = 326.11ms, Maximum = 417.02ms, Average = 349.95ms

与之前的58.43ms相比相差了291.52ms ≈ 300ms。

更真实的情况下,延迟值不会这么精确,会有一定的波动,我们可以用下面的情况来模拟出带有波动性的延迟值:

  1.  tc qdisc add dev eth0 root netem delay 300ms 50ms
  2. //该命令将 eth0 网卡的传输设置为延迟 300ms ± 50ms (250 ~ 350 ms 之间的任意值)发送

四、模拟网络中断

这次使用如下的命令:

  1. tc qdisc add dev eth0 root netem corrupt 10%
  2. //该命令将 eth0 网卡的传输设置为随机产生 10% 的损坏的数据包

此时再次执行paping命令:

 ./paping -p 80 -c 100 xxx.xxx.xxx.xxx

注意这里的次数改成了100,为了更能清楚的看到中断的实际效果。

运行这个命令的过程中,会有“Connection timed out”字样报出,类似:

  1. <snip>
  2. Connected to xxx.xxx.xxx.xxx: time=26.26ms protocol=TCP port=80
  3. Connection timed out
  4. Connected to xxx.xxx.xxx.xxx: time=65.10ms protocol=TCP port=80
  5. Connection timed out
  6. Connected to xxx.xxx.xxx.xxx: time=26.50ms protocol=TCP port=80
  7. Connected to xxx.xxx.xxx.xxx: time=25.93ms protocol=TCP port=80
  8. Connected to xxx.xxx.xxx.xxx: time=27.71ms protocol=TCP port=80
  9. <snip>

最终的统计结果如下:

  1. Connection statistics:
  2.     Attempted = 100, Connected = 90, Failed = 10 (10.00%)
  3. Approximate connection times:
  4.     Minimum = 25.67ms, Maximum = 133.77ms, Average = 51.98ms

结果显而易见,验证了此次故障模拟所对应的效果。

五、模拟网络丢包

  1.  tc qdisc add dev eth0 root netem loss 7% 25%
  2. //该命令将 eth0 网卡的传输设置为随机丢掉 7% 的数据包, 成功率为 25% 
  3. //如果不加上后面的25%,那么一丝就是随机丢掉7%的数据包

再次执行paping命令时,也会有Connection timed out报出,最终的统计结果如下:

  1. Connection statistics:
  2.     Attempted = 100, Connected = 99, Failed = 1 (1.00%)
  3. Approximate connection times:
  4.     Minimum = 25.80ms, Maximum = 133.87ms, Average = 60.94ms

7%*25%的值在1%-2%之间,符合测试的结果预期。

tc还可以模拟一些其它的网络故障,比如网络包重复、网络包错序等等,有兴趣的同学可以继续深入了解一下。

六、引申混沌工程和传统测试之间的区别

很多同学在进行一些故障测试的时候,会认为其正在进行混沌实验,其实混沌工程和传统的测试之间是有区别的。

混沌工程和传统测试(故障注入FIT、故障测试)在关注点和工具集上都有很大的重叠。譬如,在Netflix(如果还不知道Netflix是谁,可以先看看这篇《明星公司之Netflix》了解一下)的很多混沌工程实验研究的对象都是基于故障注入来引入的。混沌工程和这些传统测试方法的主要区别在于:混沌工程是发现新信息的实践过程,而故障注入则是对一个特定的条件、变量的验证方法。

当你希望探究复杂系统如何应对异常时,对系统中的服务注入通信故障(如超时、错误等)不失为一种很好的方法。但有时我们希望探究更多其他的非故障类的场景,如流量激增、资源竞争条件、拜占庭故障(例如性能差或有异常的节点发出有错误的响应、异常的行为、对调用者随机性的返回不同的响应,等等)、非计划中的或非正常组合的消息处理等等。因为如果一个面向公众用户的网站突然收到激增的流量,从而产生更多的收入时我们很难称之为故障,但我们仍然需要探究清楚系统在这种情况下的影响。

和故障注入类似,故障测试方法通过对预先设想到的可以破坏系统的点进行测试,但是并没能去探究上述这类更广阔领域里的、不可预知的、但很可能发生的事情。

在传统测试中,我们可以写一个断言(assertion),即我们给定一个特定的条件,产生一个特定的输出。测试一般来说只会产生二元的结果,验证一个结果是真还是假,从而判定测试是否通过。严格意义上来说,这个过程并不能让我们发掘出对于系统未知的、尚不明确的认知,它仅仅是对我们已知的系统属性可能的取值进行测验。而实验可以产生新的认知,而且通常还能开辟出一个更广袤的对复杂系统的认知空间。

混沌工程是一种帮助我们获得更多的关于系统的新认知的实验方法。它和已有的功能测试、集成测试等以测试已知属性的方法有本质上的区别。

七、后续

后面还会有几篇相同主题的文章发出,不出意外,下一篇应该是《怎么让进程假死》,如果有兴趣的话,可以持续关注本公众号(朱小厮的博客)。如果你还有有什么需要进一步了解的可以在下方留言,或者也聊聊你对这一块的认知和想法。


欢迎跳转到本文的原文链接:https://honeypps.com/chaos/how-to-simulate-network-fault/

 

想知道更多?扫描下面的二维码关注我

640?wx_fmt=png

相关推荐:

  • 《科普 | 明星公司之Netflix》

  • 《看我如何作死 | 将CPU、IO打爆》

 

>>>Learn More<<

 

点个"在看"呗^_^

注:本文转载自blog.csdn.net的朱小厮的文章"https://blog.csdn.net/u013256816/article/details/98140840"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top