日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

多队列 部分队列没有包_记一次TCP全队列溢出问题排查过程

發(fā)布時(shí)間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多队列 部分队列没有包_记一次TCP全队列溢出问题排查过程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
簡(jiǎn)介:記一次TCP全隊(duì)列溢出問(wèn)題排查過(guò)程

1. 前言

本文排查的問(wèn)題是經(jīng)典的TCP隊(duì)列溢出問(wèn)題,因TCP隊(duì)列問(wèn)題在操作系統(tǒng)層面沒(méi)有明顯的指標(biāo)異常,容易被忽略,故把排查過(guò)程分享給大家。

2. 問(wèn)題描述

A服務(wù)調(diào)用B服務(wù)接口超時(shí),B服務(wù)主機(jī)IOWAIT高,具體超時(shí)情況分為兩種:

  • A服務(wù)的請(qǐng)求在B服務(wù)日志中可查到,但B服務(wù)的響應(yīng)時(shí)間超過(guò)了A服務(wù)的等待超時(shí)時(shí)間3S。
  • A服務(wù)的請(qǐng)求在B服務(wù)日志中無(wú)法查到。

3. 問(wèn)題分析

此種超時(shí)請(qǐng)求集中在很短的一段時(shí)間(通常在2分鐘之內(nèi)),過(guò)后便恢復(fù)正常,所以很難抓到問(wèn)題現(xiàn)場(chǎng)分析原因,只能搭建測(cè)試環(huán)境,A服務(wù)持續(xù)請(qǐng)求B服務(wù),在B服務(wù)主機(jī)上通過(guò)DD命令寫(xiě)入大量數(shù)據(jù)造成主機(jī)IOWAIT高,同時(shí)通過(guò)TCPDUMP在兩端抓包分析。
部分服務(wù)超時(shí)日志:

  • 服務(wù)A:Get http://xxx&id=593930: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
  • 服務(wù)B: "GET xxx&id=593930 HTTP/1.1" 200 64 "-" "Go-http-client/1.1" "-" "-" 165000(單位微秒)

服務(wù)A發(fā)起請(qǐng)求3S后沒(méi)有收到服務(wù)B響應(yīng),斷開(kāi)連接,服務(wù)B日志顯示處理時(shí)長(zhǎng)為0.165S,遠(yuǎn)低于3S,服務(wù)A側(cè)看服務(wù)B的響應(yīng)時(shí)間為網(wǎng)絡(luò)傳輸時(shí)間、TCP隊(duì)列排隊(duì)時(shí)間及服務(wù)B應(yīng)用程序處理時(shí)間之和,因?yàn)槭莾?nèi)網(wǎng)測(cè)試,網(wǎng)絡(luò)傳輸時(shí)間可以忽略,主要排查方向應(yīng)為T(mén)CP隊(duì)列排隊(duì)時(shí)間。

4. 抓包數(shù)據(jù)分析

情景1:服務(wù)A及服務(wù)B均有連接日志打印。
服務(wù)A端數(shù)據(jù)包分析:
09:51:43.966553000 服務(wù)A發(fā)起 GET請(qǐng)求的數(shù)據(jù)包如下:

圖1:服務(wù)A發(fā)起GET請(qǐng)求


09:51:46.966653000 服務(wù)A發(fā)起 GET請(qǐng)求3s(即服務(wù)A設(shè)置的等待超時(shí)時(shí)長(zhǎng))后,因未收到服務(wù)B響應(yīng),服務(wù)A向服務(wù)B發(fā)起FIN主動(dòng)斷開(kāi)連接。

圖2:服務(wù)A等待超時(shí)主動(dòng)斷開(kāi)連接


09:51:59.958195000 服務(wù)A發(fā)起http請(qǐng)求16s后收到服務(wù)B的http響應(yīng)報(bào)文,因服務(wù)A已主動(dòng)關(guān)閉該連接,故直接回復(fù)RST。

圖3: 服務(wù)B16s后響應(yīng)

服務(wù)B端數(shù)據(jù)包分析:
09:51:44.062095000 服務(wù)B收到服務(wù)A發(fā)送的http請(qǐng)求包。

圖4:服務(wù)B收到服務(wù)A的請(qǐng)求


9:51:59.936169000 服務(wù)B響應(yīng)服務(wù)A,服務(wù)B從接收到http請(qǐng)求報(bào)文至響應(yīng)http請(qǐng)求總用時(shí)約為15s多,但服務(wù)B打印的日志響應(yīng)時(shí)長(zhǎng)約為0.165s。

圖5:服務(wù)B15S后響應(yīng)

圖6:服務(wù)B日志顯示響應(yīng)時(shí)間0.165s

情景2:服務(wù)A有連接日志,服務(wù)B無(wú)連接日志。
服務(wù)A端數(shù)據(jù)包分析:
09:51:43.973791000 服務(wù)A向服務(wù)B發(fā)送一個(gè)http請(qǐng)求數(shù)據(jù)包,隨后收到服務(wù)B重傳的第二次握手的syn+ack包,超過(guò)3s未收到服務(wù)B的http響應(yīng)后斷開(kāi)連接。

圖7:服務(wù)B重傳syn+ack

服務(wù)B端數(shù)據(jù)包分析:
服務(wù)B重傳了第二次握手的syn+ack包,收到服務(wù)A的http請(qǐng)求,服務(wù)B忽略,未響應(yīng),服務(wù)A等待超時(shí)后斷開(kāi)了連接。

圖8: 服務(wù)B忽略服務(wù)A請(qǐng)求

5. 根因分析

TCP在三次握手過(guò)程中內(nèi)核會(huì)維護(hù)兩個(gè)隊(duì)列:

  • 半連接隊(duì)列,即SYN隊(duì)列
  • 全連接隊(duì)列,即ACCEPT隊(duì)列

圖9:TCP隊(duì)列

TCP三次握手過(guò)程中,第一次握手server收到client的syn后,內(nèi)核會(huì)把該連接存儲(chǔ)到半連接隊(duì)列中,同時(shí)回復(fù)syn+ack給client(第二次握手),第三次握手時(shí)server收到client的ack,如果此時(shí)全連接隊(duì)列未滿(mǎn),內(nèi)核會(huì)把連接從半連接隊(duì)列移除,并將其添加到 accept 隊(duì)列,等待應(yīng)用進(jìn)程調(diào)用 accept 函數(shù)取出連接,如果全連接隊(duì)列已滿(mǎn),內(nèi)核的行為取決于內(nèi)核參數(shù)tcp_abort_on_overflow:

  • tcp_abort_on_overflow=0,server會(huì)丟棄client的ack。
  • tcp_abort_on_overflow=1,server 會(huì)發(fā)送 reset 包給 client。

默認(rèn)值是0。
情景1的抓包數(shù)據(jù)顯示連接已經(jīng)進(jìn)入全連接隊(duì)列,但是服務(wù)B日志顯示的連接時(shí)間晚了15S多,說(shuō)明連接在隊(duì)列里等待了15S后才被應(yīng)用處理。
情景2的抓包數(shù)據(jù)顯示全連接隊(duì)列已溢出,內(nèi)核根據(jù)tcp_abort_on_overflow的值為0丟棄了服務(wù)A的ack,超過(guò)了服務(wù)A的超時(shí)等待時(shí)間。
結(jié)論:服務(wù)B主機(jī)在IO達(dá)到瓶頸的情況下,系統(tǒng)CPU時(shí)間主要消耗在等待IO響應(yīng)及處理軟中斷上,服務(wù)B應(yīng)用程序獲取的CPU時(shí)間有限,無(wú)法及時(shí)調(diào)用 accept 函數(shù)把連接取出并處理,導(dǎo)致TCP全隊(duì)列溢出或隊(duì)列等待時(shí)間過(guò)長(zhǎng),超過(guò)了服務(wù)A的超時(shí)時(shí)間。

6. 如何觀察和調(diào)整tcp全隊(duì)列

圖10: TCP全隊(duì)列觀察方法

當(dāng)連接處于listen狀態(tài)時(shí):

  • Recv-Q:目前全連接隊(duì)列的大小
  • Send-Q:目前全連接最大隊(duì)列長(zhǎng)度

當(dāng)Recv-Q > Send-Q時(shí)表示全隊(duì)列溢出,可通過(guò)執(zhí)行netstat -s | grep "overflowed"命令觀察溢出情況,查看累計(jì)溢出次數(shù),如果需觀察一段時(shí)間內(nèi)的全隊(duì)列溢出情況,建議使用監(jiān)控系統(tǒng)采集數(shù)據(jù),比如prometheus。

圖11: TCP隊(duì)列溢出監(jiān)控


TCP 全連接隊(duì)列最大值取決于min(somaxconn, backlog),其中:

  • somaxconn可通過(guò)內(nèi)核參數(shù)/proc/sys/net/core/somaxconn設(shè)置,默認(rèn)值是128。
  • backlog是 listen(int sockfd, int backlog) 函數(shù)中的 backlog 大小,Nginx 默認(rèn)值是 511,可以通過(guò)修改配置文件設(shè)置其長(zhǎng)度。

7. 結(jié)語(yǔ)

本次問(wèn)題,因?yàn)榉?wù)對(duì)成功率要求很高,所以先通過(guò)調(diào)大服務(wù)B主機(jī)/proc/sys/net/core/somaxconn參數(shù)值及服務(wù)A的超時(shí)時(shí)間來(lái)緩解超時(shí)問(wèn)題,暫時(shí)保證了接口成功率。但要從根本上解決問(wèn)題,仍需解決誘因io瓶頸,因?yàn)榉?wù)B主機(jī)掛載的共享sas存儲(chǔ)集群上有其他客戶(hù)的主機(jī)偶爾io很大,影響了整個(gè)集群的性能。為解決此問(wèn)題,更換為獨(dú)享的ssd盤(pán),并通過(guò)blktrace+fio分析,將io調(diào)度算法修改為noop,io性能明顯提升,TCP隊(duì)列溢出問(wèn)題也隨之解決。

作者:陳立華

原文鏈接

本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載

總結(jié)

以上是生活随笔為你收集整理的多队列 部分队列没有包_记一次TCP全队列溢出问题排查过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。