看我如何作死 | 网络延迟、网络丢包、网络中断一个都没落下过
點擊上方“朱小廝的博客”,選擇“設為星標”
回復”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內核的流量控制,主要是通過在輸出端口處建立一個隊列來實現流量控制。
接收包從輸入接口(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平臺上測試網絡的連通性及網絡延時等。它的用法很簡單:
-p, --port N 指定被測試服務的 TCP 端口(必須); --nocolor 屏蔽彩色輸出; -t, --timeout 指定超時時長,單位為毫秒,默認值為 1000; -c, --count N 指定測試次數。比如下面的示例(記得先要開啟一個以80為端口的服務, 示例中的xxx.xxx.xxx.xxx代表ip地址):
hidden@hidden$?./paping?-p?80?-c?5?xxx.xxx.xxx.xxx paping?v1.5.5?-?Copyright?(c)?2011?Mike?LovellConnecting?to?xxx.xxx.xxx.xxx?on?TCP?80:Connected?to?xxx.xxx.xxx.xxx:?time=27.47ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=97.83ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=37.38ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=57.62ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=71.87ms?protocol=TCP?port=80Connection?statistics:Attempted?=?5,?Connected?=?5,?Failed?=?0?(0.00%) Approximate?connection?times:Minimum?=?27.47ms,?Maximum?=?97.83ms,?Average?=?58.43ms可以看到平均鏈接時間為58.43ms。
如果你的機器上沒有安裝paping,那么可以采用如下的方式安裝:
wget?https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/paping/paping_1.5.5_x86_linux.tar.gz tar?-zvxf?paping_1.5.5_x86_linux.tar.gz./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可以先安裝對應的庫來解決:
sudo?apt-get?install?libstdc++6 sudo?apt-get?install?lib32stdc++6三、模擬網絡延時
使用tc命令模擬延遲300ms(對應的刪除命令為tc qdisc del dev eth0 root netem):
?tc?qdisc?add?dev?eth0?root?netem?delay?300ms //?該命令將網卡eth0的傳輸設置為延遲300ms發送此時再次執行paping命令:
hidden@hidden$?./paping?-p?80?-c?5?xxx.xxx.xxx.xxx paping?v1.5.5?-?Copyright?(c)?2011?Mike?LovellConnecting?to?xxx.xxx.xxx.xxx?on?TCP?80:Connected?to?xxx.xxx.xxx.xxx?:?time=326.11ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx?:?time=417.02ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx?:?time=326.94ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx?:?time=326.19ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx?:?time=353.51ms?protocol=TCP?port=80Connection?statistics:Attempted?=?5,?Connected?=?5,?Failed?=?0?(0.00%) Approximate?connection?times:Minimum?=?326.11ms,?Maximum?=?417.02ms,?Average?=?349.95ms與之前的58.43ms相比相差了291.52ms ≈ 300ms。
更真實的情況下,延遲值不會這么精確,會有一定的波動,我們可以用下面的情況來模擬出帶有波動性的延遲值:
?tc?qdisc?add?dev?eth0?root?netem?delay?300ms?50ms //該命令將?eth0?網卡的傳輸設置為延遲?300ms?±?50ms?(250?~?350?ms?之間的任意值)發送四、模擬網絡中斷
這次使用如下的命令:
tc?qdisc?add?dev?eth0?root?netem?corrupt?10% //該命令將?eth0?網卡的傳輸設置為隨機產生?10%?的損壞的數據包此時再次執行paping命令:
?./paping?-p?80?-c?100?xxx.xxx.xxx.xxx注意這里的次數改成了100,為了更能清楚的看到中斷的實際效果。
運行這個命令的過程中,會有“Connection timed out”字樣報出,類似:
<snip> Connected?to?xxx.xxx.xxx.xxx:?time=26.26ms?protocol=TCP?port=80 Connection?timed?out Connected?to?xxx.xxx.xxx.xxx:?time=65.10ms?protocol=TCP?port=80 Connection?timed?out Connected?to?xxx.xxx.xxx.xxx:?time=26.50ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=25.93ms?protocol=TCP?port=80 Connected?to?xxx.xxx.xxx.xxx:?time=27.71ms?protocol=TCP?port=80 <snip>最終的統計結果如下:
Connection?statistics:Attempted?=?100,?Connected?=?90,?Failed?=?10?(10.00%) Approximate?connection?times:Minimum?=?25.67ms,?Maximum?=?133.77ms,?Average?=?51.98ms結果顯而易見,驗證了此次故障模擬所對應的效果。
五、模擬網絡丟包
?tc?qdisc?add?dev?eth0?root?netem?loss?7%?25% //該命令將?eth0?網卡的傳輸設置為隨機丟掉?7%?的數據包,?成功率為?25%? //如果不加上后面的25%,那么一絲就是隨機丟掉7%的數據包再次執行paping命令時,也會有Connection timed out報出,最終的統計結果如下:
Connection?statistics:Attempted?=?100,?Connected?=?99,?Failed?=?1?(1.00%) Approximate?connection?times:Minimum?=?25.80ms,?Maximum?=?133.87ms,?Average?=?60.94ms7%*25%的值在1%-2%之間,符合測試的結果預期。
tc還可以模擬一些其它的網絡故障,比如網絡包重復、網絡包錯序等等,有興趣的同學可以繼續深入了解一下。
六、引申混沌工程和傳統測試之間的區別
很多同學在進行一些故障測試的時候,會認為其正在進行混沌實驗,其實混沌工程和傳統的測試之間是有區別的。
混沌工程和傳統測試(故障注入FIT、故障測試)在關注點和工具集上都有很大的重疊。譬如,在Netflix(如果還不知道Netflix是誰,可以先看看這篇《明星公司之Netflix》了解一下)的很多混沌工程實驗研究的對象都是基于故障注入來引入的。混沌工程和這些傳統測試方法的主要區別在于:混沌工程是發現新信息的實踐過程,而故障注入則是對一個特定的條件、變量的驗證方法。
當你希望探究復雜系統如何應對異常時,對系統中的服務注入通信故障(如超時、錯誤等)不失為一種很好的方法。但有時我們希望探究更多其他的非故障類的場景,如流量激增、資源競爭條件、拜占庭故障(例如性能差或有異常的節點發出有錯誤的響應、異常的行為、對調用者隨機性的返回不同的響應,等等)、非計劃中的或非正常組合的消息處理等等。因為如果一個面向公眾用戶的網站突然收到激增的流量,從而產生更多的收入時我們很難稱之為故障,但我們仍然需要探究清楚系統在這種情況下的影響。
和故障注入類似,故障測試方法通過對預先設想到的可以破壞系統的點進行測試,但是并沒能去探究上述這類更廣闊領域里的、不可預知的、但很可能發生的事情。
在傳統測試中,我們可以寫一個斷言(assertion),即我們給定一個特定的條件,產生一個特定的輸出。測試一般來說只會產生二元的結果,驗證一個結果是真還是假,從而判定測試是否通過。嚴格意義上來說,這個過程并不能讓我們發掘出對于系統未知的、尚不明確的認知,它僅僅是對我們已知的系統屬性可能的取值進行測驗。而實驗可以產生新的認知,而且通常還能開辟出一個更廣袤的對復雜系統的認知空間。
混沌工程是一種幫助我們獲得更多的關于系統的新認知的實驗方法。它和已有的功能測試、集成測試等以測試已知屬性的方法有本質上的區別。
七、后續
后面還會有幾篇相同主題的文章發出,不出意外,下一篇應該是《怎么讓進程假死》,如果有興趣的話,可以持續關注本公眾號(朱小廝的博客)。如果你還有有什么需要進一步了解的可以在下方留言,或者也聊聊你對這一塊的認知和想法。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/chaos/how-to-simulate-network-fault/
?
想知道更多?掃描下面的二維碼關注我
相關推薦:
-
《科普 | 明星公司之Netflix》
-
《看我如何作死 | 將CPU、IO打爆》
?
>>>Learn More<<
?
點個"在看"唄^_^
總結
以上是生活随笔為你收集整理的看我如何作死 | 网络延迟、网络丢包、网络中断一个都没落下过的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 首发 | 中间件小姐姐直播“带货”——阿
- 下一篇: 干货!全面认识Docker和基本指令