開發(fā)或者測試互聯(lián)網(wǎng)產(chǎn)品的過程中,同學們一定遇到過connection timed out 和 socket read timed out兩種和網(wǎng)絡相關的異常。今天我們并不分析引起這些異常的原因,也不談發(fā)生異常以后的解決辦法,我們來說說如何制造這類異常,從而模擬對應的異常場景。
了解tcp協(xié)議就知道connection即建立連接的過程,其實和socket read即傳輸數(shù)據(jù)的過程并沒有太大的差別,兩者都是請求應答模式,而只是前者的請求數(shù)據(jù)量很小而已。要使兩者超時,我們可以采用相同的方法即限制網(wǎng)絡傳輸?shù)膸拋磉_到目的。
Tc即traffic control就是這樣一款能夠限制網(wǎng)絡流量的工具。Tc中主要的概念包括類class和過濾器filter。
我們可以用class把網(wǎng)絡設備的帶寬劃分成不同的區(qū)間:
tc class add dev $DEV parent 1:classid 1:11 htb rate 90mbps ceil 100mbps
tc class add dev $DEV parent 1:classid 1:12 htb rate 90bps ceil 100bps
如上,11這個class對應的帶寬 為 90到 100mbps,12這個 class對應的帶寬只有90到100bps。劃分好了class,我們就可以用filter把符合特定條件的數(shù)據(jù)包歸入不同的class中
tc filter add dev $DEV protocol ip parent1:0 prio 1 u32 match ip sport $PORT 0xffff match ip dst $IP flowid 1:12
如上就把源端口是$PORT,目的地址是$IP的數(shù)據(jù)包歸入12這個class中了,這樣就把符合該條件的數(shù)據(jù)流量限制到了90到100bps。在正在運行的系統(tǒng)中開啟上述tc限制,即把特定數(shù)據(jù)流限制到一個極小值,我們就能模擬出connection timed out異常了。
那么socket read timed out異常又該如何模擬呢,我們怎么才能區(qū)分建立連接和數(shù)據(jù)傳輸這2個過程,tc工具還能滿足我們的需求嗎?在尋找問題答案的過程中,另一個linux內(nèi)核組件iptables進入了我們的視野。
Iptables是linux系統(tǒng)中常用的防火墻組件,功能十分強大,網(wǎng)上有十分豐富的資料。由于其能夠識別數(shù)據(jù)包中的syn、ack等標志位,故能把建立連接和后續(xù)的數(shù)據(jù)傳輸過程區(qū)分開來。
iptables-A INPUT-p tcp--src $IP--dport $PORT !--syn-jDROP
如上,在目的機器上加入該條iptables規(guī)則,可以實現(xiàn)將未設置syn標志位的數(shù)據(jù)包丟棄的功能,這樣連接能夠建立完成但后續(xù)的數(shù)據(jù)傳輸將無響應。
另外,Iptables具有一種連接跟蹤機制,即能夠記錄連接的狀態(tài)。這些狀態(tài)分別是 NEW、ESTABLISHED、RELATED 和INVALID。我們可以利用該特性實現(xiàn)相同的效果。
iptables-A INPUT-p tcp-m state--state ESTABLISHED-s $IP--dport $PORT-jDROP
如上,在目的機器上加入該條iptables規(guī)則,當匹配了ip和端口,并且數(shù)據(jù)包所對應的連接狀態(tài)是ESTABLISHED 時將其丟棄。
至此read timed out異常也能輕松模擬了。Tc和Iptables是linux網(wǎng)絡模塊中強有力的工具,除了能夠利用它們開發(fā)功能,也能夠在網(wǎng)絡異常測試中發(fā)揮關鍵的作用。