閱讀341 返回首頁    go 阿裏雲 go 技術社區[雲棲]


一個api的 rt 大漲問題排查

mtop是移動接入網關平台,對客戶端暴露api,後端接api實際的應用服務,有HSF,也有http的服務端。

之前進行了機房從杭州搬遷到上海,在搬遷的過程中,其中一個api的rt突然大漲,(之前平均的約210ms)

chart_2_

分析具體的原因了,當時正機房搬遷,首先考慮的就是是否此影響,是否發生了跨機房調用的導致,當時把整個杭州的後端服務全部幹掉,確認沒有跨機房調用,但rt還是沒有降低,仍舊很高。

還是要整體性的分析,當前的情況,不存在跨機房的調用,暫僅發現此api存在rt大漲的情況,其他的api都已經實現搬遷,且rt沒有存在這種異常的大漲情況。那後續就是重點分析這個api的請求從mtop到後端的每個鏈路是否存在問題。

此api是http的接入方式,mtop對http的接入服務,采用 vipserver(軟負載均衡)分配具體機器+httpasyncclient異步callback調用模式。其他的模塊與hsf服務調用是共用的,因此排查的範圍縮減,此時查問題神器btrace出場。同事去寫腳步監控分析對vipserver以及http調用鏈路上的耗時情況。

而我則在各種數據報表上分析查看(事實證明,完善的監控報表數據是非常有效的)

mtop有個機器性能的監控報表數據(之前出現過單機問題,但整體數據上無大幅波動。雖然按機器分析報表數據量比較大浪費存儲,關鍵時刻顯作用)

排查首先發現,發現上海包間1的速度快於包間2的速度,(一個2s,一個低於1s),那就先找pe把流量全部導到rt稍微好一點的機房,但結果rt也上漲了。

再分析發現此api杭州的調用才約550ms(跨機房調用到上海的服務端,為什麼已經完全且流量到上海,可杭州機房還有流量呢?主要是客戶端上有dns緩存防攔截技術),可上海的直接機房間調用需要1.4s以上。這非常不符合常規。

首先考慮是用戶體驗,550ms總比秒級的rt好,因此先把流量導到杭州,完成一半後,rt就降低到900多ms。此時網絡那塊排查說交換機存在一定錯誤,正在處理。後續rt又出現波動。

btrace此時分析結果是rt一切正常,同時排查這個api後端應用服務確認沒有存在問題,直接在機器上curl 也是快速的。那就先考慮把此api流量全部且回杭州,切換完成後,rt降低到了450ms。這樣對用戶體驗會好很多,但問題還要繼續排查。

現在情況:
nginx(上海)===》mtop(上海)===》應用(上海)rt約1.4s
nginx(上海)===》mtop(杭州)===》應用(上海)rt約450ms

竟然繞道杭州比上海機房直接調用快,btrace分析方法的調用時間是正常的,mtop框架是基於servlet3異步+HSFcallback/http callbcak模式的(後端業務如果發生異常,rt耗時大漲,不會對mtop性能產生特別大的影響),因此剩下就要分析http的結果為什麼慢了,此刻另一神器tcpdump登場

一抓包分析就發現好幾個問題:
1、連接握手時候協商的窗口隻有1460,報文都是1個窗口在發送,協商mss是1460,可實際都是834在發送數據

2、api結果數據比較大,發生的報文非常多,因為問題1,每次都隻能一個報文發送應答後才接著發生,如果數據有40k,那差不多要傳輸50次,要50個RTT。
截取部分數據

3、上海機房的請求中經常看到超時重傳,一超時重傳最小+200ms(RTO雖然會由RTT計算確定,但當前內核限製了最小RTO是200ms,個人感覺在tcp協議設計是為防止網絡擁塞,但內網環境完全可以減少這個值,由RTT計算,畢竟相對內網丟包概率低,rtt非常小)

問題1浪費了帶寬,同時引起問題2狂發生報文,問題3會增加rt,但問題2又加劇了一個請求在問題3出現超時重傳的概率。因此很多請求從發起到結束耗時超過1s,同時發現杭州機房也有問題1和2,但丟包比較少,因此rt情況比上海的好很多。而且上海到杭州多月5ms時延,問題2多次rtt發送,50次約導致250ms浪費,看上去和之前210ms的rt比較接近。

可為什麼機器上直接curl速度正常,可程序調用就出現了上述報文的情況呢?分析tcp的參數,沒有什麼特別情況,那很大可能是應用上的問題,再看httpasyncclient的配置

screenshot
httpasyncclient在初始化時候,有對socket的SOSNDBUF和SORCVBUF設置,我們設置是1024,是否此值有關聯呢?那就進行測試,把此值去掉取默認

果然協商的窗口變為5840,再換個機器,又成14600了。原來是不同版本的內核,對接收窗口的算法有些不同,具體大家有興趣,可以查看對應版本內核的源碼

linux3內核的窗口算法
screenshot

初始的接收窗口的取值(mss的整數倍):
(1)先考慮路由緩存中的RTAXINITRWND
(2)在考慮係統默認的TCP
DEFAULTINITRCVWND(10)
(3)最後考慮min(3/4 * skrcvbuf, windowclamp),如果這個值很低

測試有效了,馬上就進行發布,mtop發布完成後,rt就降低到200ms,經過杭州繞一圈還比之前快了一點,再把流量全部切回上海,最終api的rt降低到約160ms。相比之前210ms,有50ms的rt降低。

同時因為這個參數小,如果revbuf滿了,應用沒有去取,那再有包過來,會直接丟棄,這樣引起問題3加劇,更加導致rt增長。

至於網絡上,為什麼同樣情況下上海機房http調用出現超時重傳反而比杭州還多,網絡的人正進一步分析排查

主要http接入的api不多,而且此api的數據比較大,進一步導致這問題,在處理完畢後其他http服務端的api也會帶來rt的降低

嘮叨那麼,詳細的介紹了整個問題的處理過程,rt也如第一張圖曲線波動,回過頭去分析總結這次排查的過程,主要一點點感受
1、排查問題的時候,一定要整體性的去思考,再每個節點的去分析。
2、對內核參數,要去深入的理解測試,對tcp參數的調整,要對不同版本內核對應測試分析效果

感謝同事們的全力支持和答疑 @陶輝 @畢玄 @炳天 @仲升 @洪誌 @佑明等

參考資料:
https://blog.csdn.net/zhangskd/article/details/8588202
https://blog.csdn.net/zhangskd/article/details/8200048
https://blog.csdn.net/russell_tao/article/details/18711023
https://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/
https://www.ibm.com/developerworks/cn/linux/l-hisock.html

最後更新:2017-05-23 17:32:18

  上一篇:go  什麼樣的網站建設公司才是值得信賴的?
  下一篇:go  並發集合(九)使用原子 arrays