引言:本文描述了我對于"為何請求總是延時5s"問題的分析、解決過程.
1. 初識
最近公司項目遇到一個比較奇怪的問題,現象是在我們的系統(centos6)中發的請求包,總是需要延時5s才能成功. 一想到超時,第一感覺應該就是網絡差,于是通過curl www.baidu.com
驗證,發現也是延時5s才返回,因此第一個結論:網絡差
為了進一步確認,嘗試在同一網絡下其他PC機(Windows)上訪問百度網頁,發現比較快,并確定不是緩存,于是就有了第一個疑問,"為什么相同網絡下不同PC訪問百度的時間差別這么大?"
2. 誤打誤撞
針對第一個疑問,對比了PC機的網絡配置,是完全一樣的,這就無法解釋了。就在沒有方向的時候,嘗試用IP訪問,curl 163.177.151.109
,發現速度很快,突然想到我們的請求也是使用域名. 于是自然就轉向了DNS,是不是DNS解析慢,于是嘗試更換了幾個DNS(114.114.114.114、8.8.8.8),可是發現問題依舊.
3. DNS充電
既然問題已經定位在與DNS有關,于是我查閱了資料,了解了DNS的工作流程,如下:

- 遞歸查詢 - A找B要東西;B發現自己沒有,B找C要;C給B;B再給A
- 迭代查詢 - A找B要東西;B發現自己沒有于是告知A,C有;A找C要,C給A
遞歸查詢一般用于本地DNS服務器,迭代查詢用于DNS服務器之間
言歸正傳,于是我使用nslook www.baidu.com
發現可以快速返回,因此猜測DNS可以正常獲取
4. 再抓包
為了找出原因,我使出了殺手锏,用tcpdump抓包,tcpdump -nn host 114.114.114.114
<pre>
00:27:09.459055 IP 192.168.1.88.49776 > 114.114.114.114.53: 33750+ A? www.baidu.com. (31)
00:27:09.459067 IP 192.168.1.88.49776 > 114.114.114.114.53: 46955+ AAAA? www.baidu.com. (31)
00:27:09.482865 IP 114.114.114.114.53 > 192.168.1.88.49776: 33750 3/0/0 CNAME www.a.shifen.com., A 14.215.177.37, A 14.215.177.38 (90)
00:27:14.459055 IP 192.168.1.88.49776 > 114.114.114.114.53: 33750+ A? www.baidu.com. (31)
00:27:14.482865 IP 114.114.114.114.53 > 192.168.1.88.49776: 33750 3/0/0 CNAME www.a.shifen.com., A 14.215.177.37, A 14.215.177.38 (90)
00:27:14.459067 IP 192.168.1.88.49776 > 114.114.114.114.53: 46955+ AAAA? www.baidu.com. (31)
00:27:14.482898 IP 114.114.114.114.53 > 192.168.1.88.49776: 46955 1/1/0 CNAME www.a.shifen.com. (115)
</pre>
發現客戶端發起A、AAAA的查詢,但服務端只回了A,沒有回AAAA,于是客戶端等待超時后,繼續單條單條查詢,成功返回. 為了對比,我們再正常PC上也抓包,結果如下:
<pre>
00:27:09.459055 IP 192.168.1.88.49776 > 114.114.114.114.53: 33750+ A? www.baidu.com. (31)
00:27:09.459067 IP 192.168.1.88.49776 > 114.114.114.114.53: 46955+ AAAA? www.baidu.com. (31)
00:27:09.482865 IP 114.114.114.114.53 > 192.168.1.88.49776: 33750 3/0/0 CNAME www.a.shifen.com., A 14.215.177.37, A 14.215.177.38 (90)
00:27:09.482898 IP 114.114.114.114.53 > 192.168.1.88.49776: 46955 1/1/0 CNAME www.a.shifen.com. (115)
</pre>
因此初步斷定,是由于無法獲取到ipv6地址導致延時,于是通過curl -4 www.baidu.com
發現確實沒有延時. 可是為什么會獲取不到ipv6呢,單條發送是可以正常返回,于是猜到可能是防火墻再搞鬼. 這其中正好發現了這篇《centos 6中single-request-reopen參數說明》文章
5. 結論
綜上所述,最終原因出在了防火墻上,但目前防火墻配置不在我們這邊,暫時還無法得知,但應該基本可以確定是防火墻搞的鬼,具體的解決方案在/etc/resolv.conf添加以下參數options single-request-reopen
6. 總結
以上是描述了我對"為何請求總是延時5s"問題的追蹤過程,從中學到了DNS解析流程、dig命令,可謂甚豐.