天天看點

系統原因導緻的丢包問題如何破?

本期分享專家:楓凡,曾就職于安恒資訊。目前在阿裡雲從事ecs産品的技術支援,專注于雲計算相關的安全問題以及網絡問題。堅信:“不忘初心,方得始終”

系統原因導緻的丢包問題如何破?

在你發現網站通路慢、業務不穩定的時候,你是不是也發現了伺服器的ping值很高,還經常會有丢包的情況,這些病症技術專家經常見到,也經常幫客戶分析治療此類病症,總結起來可能的原因有這幾點:營運商的網絡影響、帶寬跑滿啦、本地網絡問題、系統層面的問題等。 不過專家還說了 ,丢包隻是問題的現象,要解決丢包的病症還得找到病根。今天專家楓凡坐診為您分析丢包問題,一個案例教你如何排查系統原因導緻的丢包問題。

<b></b>

<b>問題背景</b>

<b>問題執行個體</b>:

公網ip位址  xx.xx.138.206

<b>使用者業務說明</b>:

使用者業務基于udp 協定,ecs 安裝 centos 6.5,作為中轉伺服器,收到用戶端發送的udp封包請求後,根據配置将用戶端udp封包請求轉發到其它業務伺服器。出入流量大緻持平,即流入多少流量,流出多少流量。

客戶業務正常服務時, ecs 伺服器整體的公網出入 pps(packets per second) 均在7w 左右。

<b>問題現象:</b>

客戶發現業務異常,有如下表現:

1、整體的流量情況不符合預期,流入流量明顯大于流出流量。

2、外部ip位址ping xx.xx.138.206 該ip位址都存在丢包的情況。從本機ping 外部ip位址不存在丢包情況。

3、檢視使用者曆史資料,在業務高峰期流量高于60m左右時,會出現不穩定的情況。

如下圖:

系統原因導緻的丢包問題如何破?

<b>排查思路</b>

根據使用者的回報,核心問題是udp流量轉發異常,同時發現ping丢包的症狀。如下是問題定位過程的步驟摘要:

1、通過雙向mtr指令測試,發現ecs對外通路用戶端的mtr封包第1跳就丢包。通過ecs内部tcpdump抓取網絡包也發現内部收到icmp request後并不響應。我們認為該問題與os内部相關,與中間網絡無關。

2、通過top指令檢視os内部的負載情況,發現cpu 0 跑滿,通過調整centos啟動參數保證軟中斷在多個cpu核之間均勻處理。

3、通過檢查dmesg指令輸出以及/var/log/messages等日志,發現有”bad checksum”錯誤和” _ratelimit: 25 callbacks suppressed”資訊,通過臨時關閉checksum以排除是否是因為checksum處理錯誤造成影響。

4、在進行上述分析時,使用者已經将轉發業務關閉,但仍然發現出現ping丢包的情況。

5、通過sar指令排查系統内部連接配接數情況,netstat指令檢視網絡統計資訊發現大量icmp type 3封包,通過抓包也确實發現因為業務關閉,造成ecs 傳回大量icmp type 3(port unreachable)消息。我們懷疑核心在大量icmp type 3封包的處理下,可能對icmp request封包處理存在問題。通過iptables關閉發送icmp port unreachable消息測試。

6、關閉響應icmp type 3後,發現外部ping該ecs恢複正常。同時将轉發業務開啟,發現可以正常處理業務。

<b>詳情請參考如下逐項的定位測試。</b>

<b>1、網絡測試分析</b>

通過mtr定位丢包點,如下圖雙向mtr結果:

從ecs到用戶端第一跳就開始丢包;

從用戶端到ecs,最後一跳才丢包。

<b>結論:結合抓包也發現系統收到icmp request後不響應,判斷異常是系統内部的原因導緻。</b>

系統原因導緻的丢包問題如何破?
系統原因導緻的丢包問題如何破?

<b>2、cpu負載情況分析</b>

通過top指令,發現ecs cpu 0跑滿,該情況會導緻網卡軟中斷的處理存在問題,可能出現丢包情況。

系統原因導緻的丢包問題如何破?

為了解決該問題,修改linux核心參數調優中斷的使用。

具體見:附3。

處理完成後效果如下:

系統原因導緻的丢包問題如何破?

可以看到來自網卡的網絡包處理的軟中斷在多個cpu核上均勻處理。

<b>3、系統日志層面分析</b>

dmesg指令檢視日志發現異常

如下内容的封包:

<code>udp: bad checksum. from xx.xx.86.85:54455</code> <code>to xx.xx.138.206:10315</code> <code>ulen 16</code>

系統原因導緻的丢包問題如何破?

懷疑是否是由于checksum校驗問題導緻的,于是為了排除幹擾,先關閉checksum offload功能。

通過如下指令關閉網卡checksum offload:

ethtool -k eth1 tx off

關閉後結果如下圖:

系統原因導緻的丢包問題如何破?

messages以及dmesg中都出現了如下的資訊說明

_ratelimit: 25 callbacks suppressed

懷疑該提示為日志限速,是由大量的類似如下的封包在列印到日志中,不影響業務。

udp: bad checksum. from

xxx.xx.86.85:54455 to xx.xx.138.206:10315 ulen 16

<b>4、網絡層面分析</b>

使用者臨時将轉發業務關閉,但是用戶端的流量仍然發送到該ecs。從原理上來說,轉發關閉後,該ecs的出流量應該降低很多,但是通過監控檢視發現流量,特别是pps沒有太大的變化。

如下通過sar和netstat指令在系統内部進行分析:

<b>步驟1:通過sar檢視連接配接數資訊</b>

使用指令

sar -n dev 1

檢視關閉業務後還是有大量的連接配接數,

系統原因導緻的丢包問題如何破?

<b>步驟2:通過netstat檢查各網絡協定處理情況</b>

使用指令netstat -ts進行連接配接數的統計檢視。如下圖:icmpmsg:中的outtype3類型有非常大的計數。

系統原因導緻的丢包問題如何破?

注:關于netstat –ts的詳細介紹見:附1

我們判斷大量icmp out type 3封包與使用者業務場景有關,由于使用者的業務類型為轉發類型的,即使關閉了業務,但是還是有流量流入的。udp端口關閉監聽,在收到封包的情況下,系統會響應icmp port unreachable封包。

<b>步驟3:抓包核實</b>

通過抓包确實發現了系統有type 3的回包icmp destination-unreachable

由于端口不通,主機向用戶端傳回端口不可達的封包。

注:詳細的介紹見”附2”

<b>問題定位以及解決</b>

<b>懷疑點:</b>

由于icmp封包的原因,導緻pps無法有效的下降,占用cpu資源;同時考慮大量icmp封包的發送,導緻核心在處理icmp協定時出現問題。

<b>跟進方案:</b>

使用系統防火牆iptables禁止destination-unreachable類型的封包,指令如下:

iptables -i output -p icmp --icmp-type destination-unreachable -j drop

注:該配置會影響到icmp destination unreachable的響應,目前僅作為臨時方案。

系統原因導緻的丢包問題如何破?

關閉後檢視iptables結果如附件,攔截了大量的請求,有效的降低cpu資源消耗。

系統原因導緻的丢包問題如何破?

在系統内部使用指令檢視

sar -n dev 1 10000

發送的封包明顯減少,如下圖

系統原因導緻的丢包問題如何破?

添加後測試使用者回報測試正常。

系統原因導緻的丢包問題如何破?

<b>原因分析:</b>

業務停止後,依然有流量進入伺服器,此類情況os都會回複icmp destination unreachable消息,海量的icmp處理可能導緻核心處理真正的icmp request消息存在問題。目前禁用icmp destination unreachable消息後ecs ping正常。

使用者後續恢複業務使用,回報業務正常。

關于該問題的本質應該還是在于之前的cpu 0跑滿的問題。但在排查的過程中,由于使用者停止了應用程式,導緻icmp destination unreachable 消息影響了系統對網絡icmp request的處理,誤導了排查問題的方向。

通過使用netstat指令、抓包等手段,合理的定位到問題點,先解決了icmp destination unreachable的影響,同時通過增加多個cpu處理網卡中斷,有效提升了網絡流量的處理效率,解決了問題。

<b>附1:關于netstat -ts的介紹</b>

netstat指令大家非常熟悉,一般使用者檢視系統開放的端口資訊和連接配接建立情況。在排查問題的時,經常使用netstat –antp.

這裡介紹下關于netstat 中的參數s

-s或--statistice   顯示網絡工作資訊統計表。

-t (tcp)僅顯示tcp相關選項

-u (udp)僅顯示udp相關選項

netstat -st輸出的兩個重要資訊來源分别是/proc/net/snmp和/proc/net/netstat

如果希望更多了解參數,建議通過“tcp snmp counters”搜尋了解詳情。 

本例中主要關注icmp,icmp協定的統計時在tcp以及udp下的統計結果類似,類似如下(截圖指令執行部分結果):

<code>[root@xxxxx</code>

<code>~]# netstat –ts</code>

<code>icmpmsg:</code>

<code>    intype0: 133</code>

<code>    intype3: 3934246</code>

<code>    intype8: 2211</code>

<code>    intype11: 236</code>

<code>    outtype0: 2211</code>

<code>    outtype3: 752659455</code>      <code>#out</code><code>的</code><code>type</code><code>的計數有</code><code>752659455</code><code>該值判斷異常。</code>

<code>    outtype8: 147</code>

<code>   </code>

<b>附2:關于icmp協定type 3的介紹</b>

icmp經常被認為是ip層的一個組成部分。它傳遞差錯以及其他需要注意的資訊。icmp封包通常被ip層或四層協定(tcp或udp)使用。一些icmp封包把差錯封包傳回給使用者程序。

icmp封包是在ip資料報内部被傳輸的,它封裝在ip資料報内。關于icmp的正式規範參見rfc792.

端口不可達封包,它是icmp目的不可到達封包中的一種,<b>以此來看看icmp差錯封包中所附加的資訊。舉例udp的icmp端口不可達</b>;udp的規則之一是,如果收到一份udp資料報而目的端口與某個正在使用的程序不相符,那麼udp傳回一個不可達封包。

type:3 code:3為 端口不可達

封包樣例:

系統原因導緻的丢包問題如何破?

<b>附3:cpu 0跑滿導緻網絡丢包的處理方法</b>

問題原因:

 os 預設所有的網絡中斷都是集中在 cpu 0 上的,是以 cpu 0 一跑滿就出現丢包。

問題處理:

<b>注:</b>

<b>1、重新開機生效</b>

<b>2、适用于核心2.6.32版本(centos 6系列),其他核心不适用。</b>

<b>/boot/grub/menu.lst中加入nox2apic參數</b>,

如: kernel /boot/vmlinuz-2.6.32-431.23.3.el6.x86_64 ro root=uuid=94e4e384-0ace-437f-bc96-057dd64f42ee rd_no_luks rd_no_lvm lang=en_us.utf-8 rd_no_md sysfont=latarcyrheb-sun16 crashkernel=auto keyboardtype=pc keytable=us rd_no_dm rhgb quiet nox2apic

系統層面的丢包問題你知道怎麼解了嗎?歡迎大家留言讨論,如果有想了解的技術也可以随時留言,我們下期再見。

繼續閱讀