本期分享專家:楓凡,曾就職于安恒資訊。目前在阿裡雲從事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
系統層面的丢包問題你知道怎麼解了嗎?歡迎大家留言讨論,如果有想了解的技術也可以随時留言,我們下期再見。