一個ping大包不通問題的解決過程


1、問題描述

存在問題: 深圳的采集機MQ程序無法與應用服務器進行通訊,表現為:獲取小數據時正常,獲取大數據時超時

場景圖如下

image

2、數據下載測試

使用SCP工具和FTP工具進行數據下載測試,主要是想排除采集機上MQ與應用服務器上應用的問題

2.1、在深圳采集機1上執行命令從應用服務器取數據

數據走向:應用服務器->深圳采集機1

結果:失敗

image

2.2、在深圳采集機2上執行命令從應用服務器取數據

數據走向:應用服務器->深圳采集機2

結果:失敗

image

2.3、在河源采集機上執行命令從應用服務器取數據

數據走向:應用服務器->河源采集機

結果:成功

image

2.4、在深圳采集機1上執行命令把數據傳到應用服務器

數據走向:深圳采集機1->應用服務器

結果:成功

image

2.5、在深圳采集機1上執行命令從河源采集機取數據

數據走向:河源采集機->深圳采集機1

結果:成功

image

分析:

  • 應用服務器->深圳采集機,數據傳輸不正常,出現"stalled"情況
  • 應用服務器->河源采集機 數據傳輸正常,耗時1秒
  • 深圳采集機->應用服務器 數據傳輸正常,耗時10秒
  • 河源采集機->深圳采集機 數據傳輸正常,耗時4秒

從以上得出結論

  • 排除采集機MQ的問題----使用scp和ftp工具都出現相同的問題
  • 排除應用服務器應用的問題-----深圳采集機傳輸到應用服務器正常
  • 排除深圳采集機服務器問題----河源采集機傳數據到深圳采集機正常

通過這些測試,感覺到是中間網絡的問題,但是仔細想想,又好像不對,應用服務器->深圳采集機方向就有問題,深圳采集機->應用服務器就沒問題,結合出現問題的現象:獲取小數據時正常,獲取大數據時超時,於是接下來進行ping大包數據測試

3、ping測試

同時,我也發現一個現象,從深圳采集機1上去ping應用服務器大包,超過1468byte后就不通了,在別的十多個地市采集機測試,同樣的包大小都能通,於是我嘗試在深圳和河源兩個地市進行ping然后在兩端抓包分析,進行對比

3.1、在深圳采集機上對應用服務器發起大包ping--超過1486byte就ping不成功

發起一個2000Byte字節大小的包測試。注:此處的120.83.3.10是應用服務器的另一個IP地址

ping -s 2000 120.83.3.10 -c 1

在深圳采集機上1的抓包結果為如下:有三個幀,兩個為去的,一個為返回的,有一個途中丟失了(結合下面在應用服務器收到了兩個幀,可分析出一個幀從應用服務器到采集機的途中丟失了)

image

上圖解析:

  • 采集機到達應用服務器的大包拆成了2個幀,分別是1514和562
  • 應用服務器按道理應該返回相同的數據量,但是只收到了一個562的幀,有一個1514的包在途中丟失了

注:因為鏈路層的MTU值為1500,所以包要拆分為兩個幀,MTU為1500的時候對應的length為1514

image

在應用服務器上的抓包結果為:收到了深圳采集機過來的2個幀

image

仔細分析應用服務器到采集機這個包的內容:里面的一個字段為flags為:0x02(Don’t Fragment),引起了我的注意

clip_image002[18]

3.2、在河源采集機上對應用服務器發起大包ping--可以ping成功

河源采集機上的抓包結果為(這里有4個數據包,兩個為去的,兩個為返回的)

image

應用服務器這邊的抓包結果為:成功收到采集機發過來的兩個幀

image

也仔細分析應用服務器到河源采集機這兩個包的內容:里面的一個字段為flags:分別是0X03和0X02

image

image

上網查找tcp/ip的協議的相關細節,原來這這個字段的值和含義如下:

用於標識數據幀分片是否發送完成,0X01代表“別着急,后面還有!”;0X00表示“好了,我是最后一個幀,所有幀都到齊了,你可以進行組裝了”。除此 之外,Flags字段還有一種可能就是0X02,表示該IP數據包不允許進行拆分,這時如果IP數據包長度大於鏈路MTU值,就會直接丟包。還有一種情況為0X03,表示不允許拆分,后面還有分片

1和2的分析匯總

  • 當包大小超過1476byte的時候,會拆分為多個數據包發送出去
  • 應用服務器能收到兩個地市傳過來的ICMP請求數據包
  • 河源發起ping大包測試的時候收到應用服務器返回的數據包有兩個
  • 深圳發起ping大包測試的時候收到應用服務器返回的數據包只有一個,有一個length為1514byte的包從應用服務器返回的途中丟失了

結論分析:

  • 應用服務器(solaris) 回應ping的request(即reply)的時候大包(2000byte)分成了兩個數據包,數據包的flags字段不允許分段(0X02)
  • 中間的網絡中的一個端口的MTU值小於1500,導致包(length為1514的包)直接丟失

為了進一步驗證是不是這樣,從應用服務器發起對深圳采集機和河源采集機的ping情況

3.3、應用服務器發起對深圳采集機和河源采集機的ping大包--都能ping成功

還是2000byte的測試包

深圳采集機的抓包結果:注意此處,到深圳采集機竟然分成了三個幀?為什么

image

應用服務器抓包結果

image

河源采集機的抓包結果,注意此處,到河源采集機兩個幀

image

應用服務器抓包結果

image

再進一步情況匯總:

  • 從應用服務器上是可以ping通深圳采集機和河源采集機的(因為應用服務器的request包flags字段為0X01:允許分段
  • 通過在深圳采集機上和河源采集機上的抓包對比,也可以發現從應用服務器至河源采集機的包划分為了3個數據幀,最大的一個數據幀length為1506,很明顯小於1514,少了8Byte,而且多了一個60Byte的幀

結論分析:

  • 應用服務器主動發起的包允許分段
  • 應用服務器->深圳采集機的包分成了三個數據幀,1514分成了1506和8,為什么拆分了8字節的數據出來,分析是中間經過一個MPLS網絡,加了8字節的載荷
  • 從上一條結論延伸下:ICMP包的載荷是52(很明顯60-8=52),IPv4包的載荷是24(很明顯:1514-(2000-(562-52))=24),但是為什么一個2000字節的包切割為一個IPv4和一個ICMP的包?

回到那個scp傳輸數據有誤的問題,進行抓包,發現各個數據包中的flags字段為0X02,也是不允許進行拆分包,所以傳輸有問題。

image

4、最終原因分析

  • 服務器返回的包不允許分片是其中一個原因
  • 中間經過mpls組網架構的網絡,會加上兩個標簽(8字節)的mpls包頭。通過以上針對ping大包、scp數據下載不了的分析,剛開始判斷路徑中有一台設備的端口的MTU值為1492,后來深圳檢查了深圳側的設備,各個端口的MTU值為1500。我估計是我們設備通往深圳的的采集機路徑中經過一個mpls組網架構的網絡,在這個網絡的的入口側pe會給數據包打上兩個標簽(每個標簽4字節),這樣數據包的大小就會大過1500,端口直接把包給丟棄。

所以出現ping大包不通現象,同時也是導致采集程序無法與應用服務器通訊的原因。

5、解決辦法

有三種解決方法

1、修改操作系統的限制,允許分片

2、排查應用服務器至深圳采集機服務器通過的mpls網絡節點路徑的進出端口,修改這些接口的MTU值為1508以上

3、修改應用服務器的網卡的MTU值為1492(因為中間多了8Byte的數據,從源端分片的時候預留這8Byte就行啦,目前采用了這種解決方法)

存在風險: 對於一個基於網絡的應用來講,如果應用穿過網絡的MTU與網絡上的最小MTU相等,那么應用穿過網絡的效率最高,原因是有效的避免了分片和重組。MTU從1500降到1492,在數據傳輸的效率上會有影響,但很小。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM