類比惡劣網路環境常用的幾種解決方案

來源:互聯網
上載者:User
一、利用Fiddler類比惡劣網路環境

在解決日常的支援需求中,經常會遇到一些使用者反饋一些無法簡單複現的bug,有很大一部分的bug是由於使用者自身的網路環境波動,或者是本身網路環境就較為惡劣,而服務在面對這種惡劣的網路環境的健壯性不夠,導致會出現一些意想不到的bug。而在正常的開發自測過程中很難去營造出這種惡劣的網路環境,使得這些bug較難被提前發現和修複。另外一些服務在惡劣網路環境下雖然不會出現停用情況,但是使用者體檢很差,為了最佳化這個情況下的使用者體驗,也需要去在本地類比這種環境來進行調優。 
所以要去複現這些bug,甚至是去提前發現這些bug,就需要能夠在開發環境中類比出惡劣的網路環境,從而看到在這種惡劣的網路環境下的服務的表現等。當前類比惡劣網路環境主要可以通過以下這些手段實現: 通過應用程式層或者傳輸層的Proxy 伺服器,通過在Proxy 伺服器上設定一些類比惡劣網路環境的參數,使得通過這些Proxy 伺服器的流量都被轉化為惡劣網路環境下的流量。如利用Fiddler,Charles等具有Proxy 伺服器功能的網路流量分析軟體來實現。 通過利用一些更底層的驅動層面的服務,通過控制網卡的收包發包的行為,來類比惡劣的網路環境。如dummynet的ipfw驅動等。 通過建立一個可控的網關,在網關上部署類比惡劣環境的相關程式,所有需要藉助該網關進行轉寄的流量都會被類比為惡劣網路條件。Linux下的netem就提供了這類支援。

  這裡主要先講的是第一種手段,即利用Fiddler來類比惡劣的網路環境,對服務進行測試,這個手段實現簡單,較為直觀,但是缺點是只能支援那些利用HTTP進行通訊和互動的服務。在之後的文章中也會進一步說一下後兩種手段。 【Fiddler是啥】

  Fiddler的官網上是這樣描述它自己的:The free web debugging proxy for any browser, system or platform,即跨瀏覽器、跨系統、跨平台的免費Web DebugProxy 伺服器。當你的HTTP瀏覽經過Fiddler時,Fiddler可以監視流量,查看HTTP通訊的各種資訊,設定斷點查看和修改HTTP資料,甚至可以構造各種測試用的HTTP包以及重放已記錄的包等。其官網是http://www.fiddler2.com/fiddler2/,上面詳細地介紹了Fiddler到底是什麼。 【簡單地利用Fiddler限速類比惡劣網路環境】

  Fiddler本身已經預置提供了類比Modem速度的選項,其位置位於: 
  Rules – Performances – Simulate Modem Speeds 
 
  勾選該選項後,所有通過Fiddler代理的流量都會變得和多年前的56k小貓時上網一般的慢。 
  由於Fiddler只是一個HTTP代理,要直觀地看出限速效果,最好是運行在瀏覽器中的測速工具,這裡選用speedtest.net提供的測速工具進行測試。 
  首先是開啟該選項之前的速度: 
 
  開啟了Simulate Modem Speeds後: 

  速度已經回到了當年那種無法忍受的低速了,注意到這裡PING值也有了顯著的提高,而事實上ping值是ICMP層的控制報文,並不會被Fiddler影響,理論上ping值並不會出現提高的情況,進一步分析Fiddler中的報文則可以看出端倪: 

  事實上網頁外掛程式並不能實現發送ICMP包並得到ping值的功能,而是用多次較小的HTTP GET請求的回應時間來計算PING值,這裡實際算出來的是一個平均的HTTP的RTT值,所以受到Fiddler類比惡劣環境的影響就是正常的了。 【調整類比惡劣網路環境的參數】

  直接類比Modem速度實在是慢爆了,事實上就算是在很差訊號的情況下,手機移動網路的速度都已經超過了當年的56k Modem速度了,所以採用預設的配置類比出來的環境過於惡劣,並不一定符合需求,此時就需要對限速的參數進行調整。 
  Fiddler本身就提供了一個設定檔供調整這些參數,點擊: 
  Rules – Customize Rules… 
  就會用文字編輯器開啟CustomRules.js檔案,其預設位於使用者目錄的文檔目錄下的\Fiddler2\Scripts 位置,尾碼名是js,其內容實質是JScript.NET——微軟對ECMAScript規範的實現,與日常使用的javascript是屬於同一個規範下的,但是在擴充的細節實現存在一定的不同。 
  開啟該檔案後,可以找到一個m_SimulateModem標誌位:

if (m_SimulateModem) {    // Delay sends by 300ms per KB uploaded.    oSession["request-trickle-delay"] = "300";    // Delay receives by 150ms per KB downloaded.    oSession["response-trickle-delay"] = "150"}

   該標誌位控制著oSession的兩個參數值的設定,當勾選了Simulate Modem Speeds時,request-trickle-delay與response-trickle-delay就會被設定,其中request-trickle-delay中的值代表每KB的資料被上傳時會被延時多少毫秒,response-trickle-delay則對應下載時每KB的資料會被延時多少毫秒,如果本身網速已經相當快的話,這裡設定的值就可以近似地推算出開啟類比後的上傳和下載頻寬了,比如預設設定下下載延時為150ms,上傳延時為300ms,對應可以推算出大致的類比頻寬為:

上傳頻寬=(1*8/1000)/0.300≈0.053Mbps 
下載頻寬=(1*8/1000)/0.150≈0.027Mbps

  然而實際情況下卻得到了兩倍於這個值的頻寬,推測可能是Fiddler的內部實現上有一些和描述上的不同,為何為造成這個現象現在還不是很清楚,所以上述公式最後還需要修正一個2.0的係數,即:

上傳頻寬=((1*8/1000)/0.300)*2.0≈0.106Mbps 
下載頻寬=((1*8/1000)/0.150)*2.0≈0.053Mbps

  假設我們將兩個參數都設定為50,則會得到上下載頻寬均為0.32Mbps,測速結果如下所示: 
【編寫自訂指令碼】

  進一步地,我們可以擴充CustomRules.js裡的邏輯,參照Jscript的文檔可以在類比惡劣環境中加入更多自訂的邏輯,這裡實現了一個隨機延時量設定,使得網路頻寬不是恒定為一個低速的值,而是會在一定範圍內隨機抖動:

static function randInt(min, max) {    return Math.round(Math.random()*(max-min)+min);}if (m_SimulateModem) {    // Delay sends by 300ms per KB uploaded.    oSession["request-trickle-delay"] = ""+randInt(1,50);    // Delay receives by 150ms per KB downloaded.    oSession["response-trickle-delay"] = ""+randInt(1,50);}
1 2 3 4 5 6 7 8 9

  得到的測試結果如下: 
 
  在測速過程中的瞬時速度的趨勢圖如下: 
 
  可以看到整體的網路限速存在了一定程度的抖動。 
  通過進一步擴充CustionRules.js可以實現很多需要的惡劣環境類比情境,如果情境較為複雜的話,也可以通過編寫Fiddler的外掛程式的方式,編寫C#外掛程式代碼來進一步控制Fiddler的行為,在這裡就不多做贅述了。詳細可以參照:http://docs.telerik.com/fiddler/extend-fiddler/extendwithdotnet 【Fiddler類比惡劣網路環境的局限性】

  Fiddler進行限速較為簡單和靈活,配置也較為方便,但是由於它是一個應用程式層的HTTP的代理,只能類比該層上的行為,對於一些複雜的網路層的丟包、重傳等惡劣情況就不能很好的類比出來,而且對於其他協議的應用也不支援,後續會介紹一些其他的類比惡劣環境的方法和軟體來彌補這些缺失。

 

  二、利用Dummynet類比惡劣網路環境 利用Dummynet類比惡劣網路環境

在之前的文章中提到了三種類比惡劣網路環境調試代碼的手段: 應用程式層或者傳輸層的Proxy 伺服器 傳輸層或者網路層控制資料包的驅動 網路層控制資料包的網關

同時在之前的文章中介紹了第一種手段,即利用應用程式層的HTTP代理Fiddler來類比惡劣網路環境,這種方式簡單且靈活,但是其處於應用程式層,限制較大,同時也沒有辦法從頻寬和延時兩個方面分別去精細化地對惡劣網路環境進行類比,這裡介紹第二種手段——Dummynet。 Dummynet簡介

Dummynet的官網地址是:http://info.iet.unipi.it/~luigi/dummynet/,官網上對於dummynet的描述是這樣的:dummynet is a live network emulation tool, originally designed for testing networking protocols, and since then used for a variety of applications including bandwidth management. 即Dummynet是一個即時的網路類比工具,事實上dummynet是ipfw防火牆的一部分,ipfw是一個網路層的防火牆,並內建於FreeBSD之中。 
利用ipfw的options DUMMYNET選項,可以設定一系列的pipes,從而做到對網路流量進行控制的目的。
Dummynet基本原理

 
如官網上提供的這張圖所示,dummynet通過在兩個網路層中(一般是在傳輸層和應用程式層之間或者網路層與傳輸層之間)建立一條條pipe的方式來控制網路流量,符合設定的規則中的網路流量會被引入這些管道中去,從而使得dummynet可以介入這些流量之中,控制頻寬、延遲,甚至進一步控制丟包率等眾多參數。
Dummynet安裝(Windows)

Dummynet本身作為ipfw防火牆的一部分,其內建於FreeBSD,其本身支援FreeBSD,OSX,Linux,Windows多種作業系統下的安裝和使用,在OSX和Linux下下載源碼編譯安裝一般即可使用,這裡主要介紹一下Windows下的Dummynet安裝。 
Dummynet在Windows下是作為一個網卡上的服務驅動存在的,在官方給出的二進位檔案包中已經包含了該驅動的sys與inf檔案,但是該驅動是沒有包含數位簽章的,在並沒有引入驅動強制籤名機制的Windows作業系統(如Windows XP)上時,直接到官網下載到最新的二進位包,然後依照之後的操作步驟進行安裝即可以完成ipfw+dummynet服務驅動的安裝,但是在引入了驅動強制籤名機制(一般是Windows 7以後的Windows版本,或者設定了比較嚴格的組策略)的作業系統上,是無法安裝ipfw+dummynet服務驅動的,要解決這個問題可以使用兩種方案: 開啟Windows的測試模式,關閉驅動強制籤名機制,然後安裝無簽名的驅動 
這種方式的實現也有兩種方式,一種是在啟動Windows時啟動選項中關閉驅動強制籤名校正機制,可以參考這篇文章 http://jingyan.baidu.com/article/7c6fb42879543380642c9036.html ,另外一種方式則是進入Windows的測試模式,可以參考 http://jingyan.baidu.com/article/acf728fd21c3e7f8e510a3ef.html 文章中的說明。 為無簽名的ipfw+dummynet服務驅動打上自簽名或者可用的簽名 
如何進行自簽名或者打上可用的簽名可以參考MSDN上的說明 https://msdn.microsoft.com/en-us/library/windows/hardware/ff544865(v=vs.85).aspx ,具體如何簽名並不在本文的範疇內。 
本文主要使用第二種方式,為ipfw+dummynet服務驅動打上百度簽名後,即可在Windows 7上正常安裝。

安裝的方式如下: 找到你需要限制頻寬和流量的網卡,進入屬性: 
點擊下方的安裝,選擇服務,然後選擇從磁碟安裝,並在瀏覽中找到ipfw+dummynet服務驅動的inf安裝檔案: 
在“此串連使用下列項目”中看到ipfw+dummynet之後,即代表ipfw+dummynet服務驅動安裝成功,如果安裝成功後遇到網卡無法使用的情況,一般會是前一次卸載沒有卸載完全,重啟電腦可以解決。 
安裝完成後可以以管理員權限運行binary目錄下的testme.bat,如果運行結果中沒有警示資訊或者錯誤資訊,則驅動安裝是成功的: 
利用Dummynet類比惡劣網路環境

利用dummynet的pipe,可以設定一些特定的規則,就可以達到類比惡劣網路環境的目的,且這些設定對於在作業系統中啟動並執行應用程式來說是透明的、自動生效的,不需要像在使用Fiddler來進行類比時還需要設定http代理。 低頻寬類比 
惡劣網路環境最基礎的類比方式就是類比較小頻寬下的情況,利用dummynet中的pipe設定,可以將所有的tcp流和udp流的頻寬節流設定在一定的層級上,運行一個管理員的命令列,並利用binary目錄下的ipfw.exe檔案就可以設定dummynet中的pipe,在命令列中執行以下命令: 
ipfw add pipe 2 in proto tcp 
ipfw pipe 2 config bw 2Mbit/s 
即可將tcp的下行流量限制在2Mbit/s的頻寬上,這裡採用和上一篇文章中採用的相同的測速網站speedtest.net來驗證限制頻寬的效果,在執行以下指令以前的測速結果如下: 

在執行完上述指令以後的測速結果如下: 
高延時類比 
在管理員權限的命令列中執行以下命令: 
ipfw add pipe 10 ip from any to any 
ipfw pipe 10 config delay 200 
這會使得所有的包都被延時200ms,這裡利用ping命令來ping百度的方式來直接測試延時,命令執行以前結果如下: 

命令執行以後結果如下: 
高丟包率類比 
在管理員權限的命令列中執行以下命令: 
ipfw add pipe 10 ip from any to any 
ipfw pipe 10 config plr 0.1 
這裡設定的是10%的丟包率,這裡利用ping -t指令繼續ping百度,來觀察丟包率的變化: 
執行以前: 
 
執行以後: 
更加精細化的設定 
可以看到相比Fiddler來說,利用dummynet可以更加精細化地從各個角度去設定一個惡劣網路環境的參數,上文中提到的頻寬、延時和丟包率的類比當然也可以組合起來使用,同時在設定pipe規則時還可以進一步設定更加精細的規則,比如指定的ip段,指定的協議等,比如這一段指令: 
ipfw add pipe 4 src-ip 10.1.2.0/24 in 
ipfw pipe 4 config bw 1Mbit/s delay 123 plr 0.1 
就設定了一個只會介入源ip來自10.1.2.0/24網段的資料包的pipe,並且這個pipe會限制1Mbit/s的頻寬,延時123ms,並且有10%的丟包率,通過組合這些參數,可以類比出很複雜的惡劣網路環境,從而滿足開發與測試的需要。相關的設定參數的說明和設定方法可以參考官網的相關文檔和其他的一些說明文檔。

在最後,當完成類比惡劣網路環境後,執行以下命令: 
ipfw -q flush 
ipfw -q pipe flush 
來清除所有設定的pipe和規則,進一步如果需要還原原來的環境的話可以將驅動刪除,並重啟電腦即可。

 

  三、clumsy 0.2類比網速

clumsy 能在 Windows 平台下人工造成不穩定的網路狀況,方便你調試應用程式在極端網路狀況下的表現。 簡介

利用封裝 Winodws Filtering Platform 的WinDivert 庫, clumsy 能即時的將系統接收和發出的網路資料包攔截下來,人工的造成延遲,掉包和篡改操作後再進行發送。無論你是要重現網路異常造成的程式錯誤,還是評估你的應用程式在不良網路狀況下的表現,clumsy 都能讓你在不需要額外添加代碼的情況下,在系統層次幫你達到想要的效果:

特色: 下載即用,不需要安裝任何東西。 不需要額外設定,不需要修改你的程式的代碼。 系統層級的網路控制,可以適用於命令列,圖形介面等任何 Windows 應用程式。 不僅僅只支援 HTTP,任何 TCP, UDP 的網路連接都可以被處理。 支援本地調試(伺服器和用戶端都在 localhost) "熱插拔",你的程式可以一直運行,而 clumsy 可以隨時開啟和關閉。 即時調節各種參數,詳細控制網路情況。 執行個體

下面的動畫展示了 clumsy 作用於一個本地的基於 netcat 的 UDP 伺服器/用戶端的情況。仔細觀察你可以看到資料根據在 clumsy 的影響下產生了相應的變化。 如果你基本知道了 clumsy 是幹什麼用的,不妨到下載頁面選擇適用於你系統的版本進行下載。

詳細資料

clumsy 首先根據使用者選擇的 filter 來攔截指定的網路資料。在 filter 中可以設定你感興趣的協議(tcp/udp),連接埠號碼,是接收還是發出的連接埠。你也可以通過簡單的邏輯語句來進一步縮小範圍。當 clumsy 被啟用時,只有符合這些標準的網路資料會被進行處理,而你不感興趣的資料仍然會由系統正常傳輸。

當被 filter 的網路資料包被攔截後,你可以選擇 clumsy 提供的功能來有目的性的調整網路情況: 延遲(Lag),把資料包緩衝一段時間後再發出,這樣能夠類比網路延遲的狀況。 掉包(Drop),隨機丟棄一些資料。 節流(Throttle),把一小段時間內的資料攔截下來後再在之後的同一時間一同發出去。 重發(Duplicate),隨機複製一些資料並與其本身一同發送。 亂序(Out of order),打亂資料包發送的順序。 篡改(Tamper),隨機修改小部分的包裹內容。

儘管當前寬頻網路串連十分普及,但網路傳輸其本身在本質上總不是穩定的。如果你的應用程式中沒有應對各種情況的處理,那麼有可能一個丟失的 UDP 包裹都會讓你的程式崩潰。正確的調試這類行為 顯然需要再代碼結構上進行仔細的設計和處理,還會很花功夫。而且在某些封裝緊密的開發環境(Unity3D 內建的網路程式庫可能是一個例子)下會更麻煩。clumsy 以儘可能減輕程式員負擔為目標, 希望提供一個簡單方便(但並不完美)的解決方案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.