一個詭異的網絡問題追蹤

最近設計部報告說經常發生終端鏈接忽然紅屏的現象。一天會發生幾起。範圍還挺大


這是RGS協議丟包的表現。

本來以爲是服務器端帶寬原因,因爲以前發生過類似的情況。經過排查,發現並不是這樣的。服務器端並不存在帶寬瓶頸。而且出現問題的服務器分佈也比較均勻。

再看接入層,發現交換機的接入端口上的output錯包都是天文數字,錯包類別是abort。以前看過的資料對於abort錯誤是這樣解釋的:abort錯誤包含了前導幀出錯,以及不在其他統計類別中的所有錯誤的總和。

這個解釋範圍太大了,沒什麼實際意義。

怎麼回事?難道是所有端口同時都壞了?這不可能啊。繼續觀察,發現所有端口的錯包程週期性增長,每隔一段時間,大概有幾十秒,錯包就飆升一下。第一反應,可能是存在一個電磁干擾源,這個干擾源以特定週期發出干擾信號。上聯端口是光纖,沒有收到干擾。我不知道這個解釋能否行得通,因爲干擾應該是crc錯誤比較合理。因爲從來沒遇到過電磁干擾,不知道現象是什麼樣的。不過有一個簡單的辦法來驗證這個理論,我又拿了一臺交換機沒做任何設置橋接在這臺交換機下,並把一部分用戶遷移過來。如果兩臺設備問題同時發生,證明這個理論可能正確,可以進行下一步診斷,否則說明這個推斷錯誤。事實證明,電磁干擾假設是錯誤的。新的交換機端口並沒有錯誤。我又把這臺交換機通過trunk連接到主幹路,錯誤激增!

很顯然,是主幹路的某種報文引起的接入端口的鏈路錯誤。居然有這種事情,真是匪夷所思。不過值得高興的是,並非硬件出現故障。否則後果真的太嚴重了。

我又看了其他樓層的交換機,居然所有樓層不同vlan都是這個情況。又看了一下其他辦公樓,問題雖然沒有這麼嚴重,但是錯包的分佈依然比較普遍。

是什麼樣的報文能夠導致這樣的問題出現呢?

我的一個同事打電話求助h3c。廠商工程師給出的解釋是可能是千兆端口下來的突發流量讓百兆端口的緩衝區容納不下,導致丟包。聽起來很合理,不過如果是發生了這種情況,錯誤報文應該被計入到underrun統計中,而不是abort錯誤。另外,h3c裏面有個功能叫做burst-mode專門爲了適應這種情況。這是我本來就知道的,敲一條命令不費什麼事,遺憾的是,burst-mode和我們普遍採用的交換機堆疊設置有衝突。

不管怎樣,如此大範圍的影響應該是廣播包。我和幾個同事把全部接入層和核心的端口都做了廣播抑制。問題似乎有了好轉,錯包數量下降了好幾個數量級。

我們又新建了一個vlan,只放了幾個用戶進去。這個新的vlan果然沒有錯包。

雖然有還是有很多錯誤,但是已經紅屏現象似乎得到了遏制。不過這樣的結果,證明了流量說是不正確的。

這樣,又產生了新的問題:

1.排除了流量原因,那麼導致錯包的原因是包的類型。除了bug,很難解釋這是怎麼發生的。這種情況也不是沒發生過。以前遇到過新買的設備,總時不時的不轉發arp,查了一天都沒結果。後來給交換機系統升了個級,就解決了。但是升級的patchnote裏面沒有任何關於這個問題的描述。還有一次,某個交換機一根網線一旦插上,10秒鐘之內cpu就會上升到100%,cpu都被info進程搶佔。重新做了根線,問題就解決了。


2.如果是廣播引起的問題,爲什麼所有的vlan都會受到影響。這個現象說明引起問題的根源出在核心交換機。

3.用戶數據中斷和端口錯包是不是有必然的聯繫?因爲紅屏現象肯定是用戶的tcp會話包丟失導致的。但是統計裏的大部分錯包應該是廣播包本身,而非用戶數據。

不管怎樣,還是抓包看看。假設類型說是正確的,即使接入層的abort錯包無法抓取,那麼從千兆上行口抓到的報文一定能找到導致問題發生的報文類型。

出於方便,我先抓一下接入層的包,看看都能收到哪些類型的廣播。

wireshark顯示,大部分廣播以arp爲主,還有一些NetBIOS的報文以及其他二層報文。

有兩個現象比較引人注意:

1.arp報文中有每隔一段時間就有一大批從核心交換機,也就是網關發來的arp報文。檢查了一下,都是不存在的地址。說明很可能有人在對這些不存在的地址進行掃描。h3c有一個針對這種情況的解決方案,叫做arp源抑制。如果某一個ip不斷地掃描不存在的地址,5秒內超過一定閾值,就會再接下來的5秒把這個ip來的報文都丟掉。治標不治本,聊勝於無吧。

2.有相當多的用戶發出的arp包的校驗錯誤。這些校驗錯誤有個共同的特徵。同樣用戶發出的所有包的錯誤校驗碼都是相同的,而且所有錯誤的校驗碼的最後兩個字節都爲0。顯然這不是隨機發生的現象,而是校驗算法出現了問題。

首先,這些錯包和output錯包不是同一個概念。output錯包應該是抓不到的。端口計數器證實了這個觀點。

其次,這個校驗算法出現的故障應該是出現在交換機端,而非用戶端。因爲從用戶端發出來的數據如果校驗出錯直接就被端口丟棄了,根本不可能得到轉發。在用戶端抓包證明了這個觀點,用戶端發出去的包是沒問題的。按照通常的想法,校驗通過就就可以原封不動的轉發了。可能是這段的程序出現了什麼問題。

不管如何,既然錯成這樣。那麼我先假設這個算法可能出現問題了。抱着試試看的想法我先假設他錯的原因是crc校驗的生成多項式不對。(當然,現代crc算法都是採用的查表發,而非計算法。也有可能是crc表錯誤,這個我先不考慮。)按照他錯誤的方式把crc算法的生成多項式的方程解出來,如果這個生成多項式在所有報文中一致,就證明了這個猜測。

4個字節的fcs,應該是crc32。我先試了下把crc16的生成多項式帶入原報文,結果和錯誤不吻合。

我假設原始數據爲d,生成項爲m,是一個33bit的值。校驗結果爲r。那麼對於crc32的校驗方式應該是d<<32=r(mod m)。

我的目的就是在知道d和r的情況下解出m。這個問題換個表達法就是d<<32-r可以被m整除。也就是說m應該是(d<<32)-r的因子。把(d<<32)-r做因式分解,找到其中能夠組合成33bit的因子就行。

可是,d<<32的數是一個10^170的巨大數字。即使兩個報文的數據做差分,還是在10^150左右。。根本就無法分解。換個思路,我的假設是錯誤的生成多項式是相同的,那麼這個m應該是兩個不同的(d<<32)-r的公因子。我先用歐幾里得除法解出這兩個數的最大公約數。再對這個最大公約數進行因式分解就可以了。

結果,這兩個數的最大公約數是65536,剛好是錯誤的校驗的最後2字節0。除了兩個字節部分,其他部分都是互質的。猜測失敗。。。(本來我也沒覺得能夠成功)。

當時第一反應是隨便找到這麼大的兩個數互質的概率有多大?查了一下關於歐拉函數的wiki,裏面有個公式,在n接近無窮大的時候,從1...n隨便找兩個數互質的概率是6/pai^2。接近2/3的概率,還是挺大的。不瞎折騰了,此路不通。


故障的原因在此陷入僵局。雖然問題表面上得到了解決,但是問題的原因還是沒有得到合理的解釋。有些地方,錯包還是在增長。感慨自己的水平和經驗太有限了,也許對於一些專家和高手這個問題是很淺顯的。


記得在微軟technet上看過這樣一個故障:windows系統崩潰的時候會把崩潰信息發給微軟。讓微軟的工程師查看問題。其中有一個故障發生的很普遍。根據dump出來的堆棧和寄存器信息。微軟的工程師發現問題發生的原因出在xor eax,eax這條命令上,這條命令是把eax置零的最快操作。在程序中存在極大量的類似指令。在故障中,xor eax,eax後,eax卻不等於零。相當於計算機把1+1算成了不等於2。只能理解成cpu壞了。微軟的工程師百思不得其解,因爲這個故障發生的的頻率非常高。後來,一個偶然的原因。微軟的工程師發現,這些故障中的很多電腦都對cpu進行了超頻。

原來如此。。。


把這個故障做一個記錄,也許某一天能夠知道是怎麼回事。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章