一 、之前的舊經驗
之前公司發生過wget過慢的情況,經過研究發現wget默認調用系統的getaddrinfo,會同時發送ipv4和ipv6的dns請求,只有當2個都收到或者ipv6超時時,纔會進行下載流程。
而公司使用的dns不響應ipv6的請求,導致每次wget前都要在dns階段卡頓5秒鐘(等待超時),解決辦法是修改了dns代碼,遇到ipv6的請求後,直接返回空數據,有效解決了wget等一系統使用getaddrinfo函數的程序速度慢的問題。
二、第一反應
所以平時在操作中遇到ping首包慢的情況,潛意識裏覺得應該是ipv6的問題,沒有太過關注。但是幫同事解決問題的時候發現,首包卡頓是不定期的,而不是默認5秒鐘。
三、抓包分析
感覺很奇怪,於是抓包看了一下,發現dns返回速度很快,也沒有請求ipv6的域名地址,同時ping包的request和reply都很快。可是明明已經收到了reply,ping首包依然處於卡頓狀態。
抓包發現icmp瞬間返回。
但是顯示時間巨慢,需要等待3s。
於是對dns也進行抓包
發現在dns解析,ping響應後,又多了一步dns 用ip反查域名,耽誤了很多時間。
四、解決問題
man了ping發現有個配置
-n Numeric output only. No attempt will be made to lookup symbolic names for host addresses.
使用這個參數解決了首包延遲的問題。
另外如果直接ping ip地址,也不會去反查dns。
五、後續問題
在公司內網測試的時候發現ping包經常收不到應答,但是抓包都是響應了的,於是把抓包拿到本地分析。
ping包的icmp是沒有端口的,所以通過裏面的字段來確定報文是誰發送的,有各個監控進程來自己選擇處理響應結果。
如上請求包
如上響應包
但是在第二組抓包裏面發現,響應包和請求包的標識字段不一致,沒有使用同樣的id,而是使用了上一次的識別字段,估計防火牆做了什麼保護處理,把上一次的ping包結果給緩存的,用來響應新的ping請求。結果導致了故障。使得ping時通時不通。
所以說如果對協議瞭解的不清楚,不要隨便給人做緩存。