短鏈接timeout的問題

短鏈接的time_out的問題(我們組的人對線上業(yè)務(wù)的改進)

問題現(xiàn)象:

yp_fras前段時間經(jīng)常會大量出現(xiàn)錯誤號為110的connection time out 錯誤

691: yp_wp075v.add.bjdt.qihoo.net [2016/06/12:14:52:03] access [xxx.xxx.xxx.xxx:9869] table: yp_fras catch exception in __construct: [BadaSocket: Could not connect to xxx.xxx.xxx.xxx:9869 (連接超時 [110])]

692: yp_wp023v.add.bjdt.qihoo.net [2016/06/12:14:52:03] access [xxx.xxx.xxx.xxx:9869] table: yp_fras catch exception in __construct: [BadaSocket: Could not connect to xxx.xxx.xxx.xxx:9869 (連接超時 [110])]

693: yp_wp089v.add.bjdt.qihoo.net [2016/06/12:14:52:03] access [xxx.xxx.xxx.xxx:9869] table: yp_fras catch exception in __construct: [BadaSocket: Could not connect to xxx.xxx.xxx.xxx:9869 (連接超時 [110])]

694: yp_wp080v.add.bjdt.qihoo.net [2016/06/12:14:52:07] access [xxx.xxx.xxx.xxx:9869] table: yp_fras catch exception in __construct: [BadaSocket: Could not connect to xxx.xxx.xxx.xxx:9869 (連接超時 [110])]
1: yp_wp054v.add.bjdt.qihoo.net [2016/0

問題結(jié)論

這個問題是由大量的短鏈接造成的哩陕,據(jù)初步統(tǒng)計兼搏,有近百臺客戶機上部署有訪問bjdt機房yp_vrs的客戶端青灼,每個客戶機上又有不少的客戶端濒生。當(dāng)這些客戶端在某個時刻以短鏈接的方式集中訪問服務(wù)端時,TCP連接建立的壓力是比較驚人的登澜。

客戶端大量的短連接請求兆衅,使得服務(wù)端的listen端口的ACCEPT隊列產(chǎn)生溢出,從而不接受新的連接請求攀例,連接失敗,導(dǎo)致”[110][connection time out]”報錯顾腊。

改進意見

提高客戶端的鏈接超時限制粤铭。當(dāng)前是300ms,比如可以提升到3s等杂靶;(治標(biāo)不治本)
提高服務(wù)端的somaxconn限制梆惯,這也是個治標(biāo)不治本的方法酱鸭,只能是一定程度的緩解。(修改內(nèi)核的其他的網(wǎng)絡(luò)參數(shù)也是一樣加袋,只能是緩解,并不能解決根本問題)
在客戶端使用連接緩沖池抱既,將短鏈接轉(zhuǎn)換成長鏈接來使用(個人認(rèn)為這個才是更好的辦法职烧,一勞永逸)

問題分析

Linux的服務(wù)端從listen的端口建立的連接要經(jīng)過兩個隊列的過渡,分別是SYN隊列和ACCEPT隊列防泵。服務(wù)端接受到SYN請求后蚀之,會發(fā)送SYNACK,并把這個request sock存在SYN隊列內(nèi)捷泞;等到三次握手完成后足删,再存放到ACCEPT隊列內(nèi);然后再由accept系統(tǒng)調(diào)用锁右,從ACCEPT隊列內(nèi)拿出失受,交給用戶使用。
SYN隊列和ACCEPT隊列都是有長度限制的咏瑟,這個長度限制與以下三個參數(shù)有關(guān):

  • a. 調(diào)用listen接口拂到,傳遞給back_log參數(shù);
  • b. 內(nèi)核參數(shù)somaxconn; //與ACCEPT隊列相關(guān)
  • c.內(nèi)核參數(shù)tcp_max_syn_backlog码泞; //與SYN隊列相關(guān)
    我們線上的問題主要是ACCEPT隊列出現(xiàn)溢出造成的兄旬,所以這里主要分析ACCEPT隊列長度限制的情況
    在調(diào)用listen接口的時候,內(nèi)核會用系統(tǒng)的somaxconn參數(shù)去截斷傳遞給listen的back_log參數(shù)余寥,下面是linux2.6.32-70的相關(guān)代碼片段
@sock.c
SYSCALL_DEFINE2(listen, int, fd, int, backlog)
{
......
        if ((unsigned)backlog > somaxconn)
            backlog = somaxconn; //被截斷
......
            err = sock->ops->listen(sock, backlog);//調(diào)用的就是下面的inet_listen函數(shù)
......
}

@af_inet.c
int inet_listen(struct socket *sock, int backlog)
{
......
    sk->sk_max_ack_backlog = backlog;
......
}

上面的sk_max_ack_backlog就是listen端口的ACCEPT隊列的最大長度
當(dāng)短鏈接的量太大领铐,accept系統(tǒng)調(diào)用接口處理來不及時,ACCEPT隊列就可能會阻塞溢出宋舷,這個時候绪撵,Linux的TCP/IP協(xié)議棧的做法是把新來的SYN請求丟棄掉( Accept backlog is full. If we have already queued enough of warm entries in syn queue, drop request. It is better than clogging syn queue with openreqs with exponentially increasing timeout.),這樣當(dāng)客戶端設(shè)定的連接超時不夠發(fā)送第二次SYN請求時祝蝠,就會收不到服務(wù)端ack莲兢,連接建立失敗,這個時候報的錯誤是ETIMEDOUT续膳,也就是“[110][connection time out]“改艇。下面是linux.2.6.32-70的相關(guān)代碼片段

@tcp_ipv4.c
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
......
    if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) //inet_csk_reqsk_queue_young(sk) 表示SYN隊列中還沒有握手完成的請求數(shù),也就是young request sock的數(shù)量
        goto drop;//丟棄這個SYN請求
......
}

@sock.h
static inline int sk_acceptq_is_full(struct sock *sk)
{
    return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}

在上面的代碼段中坟岔,sk_acceptq_is_full(sk)是判斷ACCEPT隊列是否滿了(隊列長度限制已經(jīng)在listen系統(tǒng)調(diào)用中被截斷了谒兄,這也是為什么我們修改內(nèi)核somaxconn內(nèi)核參數(shù),對當(dāng)前應(yīng)用程序的已經(jīng)listen的端口的ACCEPT隊列長度限制不產(chǎn)生影響的原因社付,需要重起承疲,才能夠使用新的內(nèi)核參數(shù))邻耕,如果滿了,而且SYN隊列中又有新的沒有完成握手的連接請求燕鸽,則丟棄當(dāng)前這個鏈接請求兄世,這個時候的如果客戶端設(shè)置的鏈接超時只夠它發(fā)送一次SYN請求,則鏈接失敗啊研,發(fā)生“[110][connection time out]“報錯御滩。
驗證:

  • 按照線上情況,設(shè)置somaxconn為128,listen接口的back_log為8192 運行一定數(shù)量的客戶端党远,頻繁的向服務(wù)端建立TCP鏈接削解,然后釋放,觀察情況
  • 設(shè)置somaxconn為8192, 同時設(shè)置listen的接口的back_log參數(shù)也為8192,重復(fù)1的步驟
<?php
while (true) {
  $fp  =  fsockopen ( "10.138.79.205" ,  8221 ,  $errno ,  $errstr ,  0.5 );
  fclose ( $fp );
}
?>

上面是單個客戶端的代碼邏輯沟娱,很簡單氛驮。

somaxconn為128。 
客戶端大量報錯
PHP Warning:  fsockopen(): unable to connect to xxxxxxxxxxx:8221 (Connection refused) in /home/wxf/sample.php on line 3
PHP Warning:  fsockopen(): unable to connect to xxxxxxxxxxx:8221 (Connection refused) in /home/wxy/sample.php on line 3
PHP Warning:  fsockopen(): unable to connect to xxxxxxxxxxx:8221 (Connection refused) in /home/wxy/sample.php on line 3
....

服務(wù)端的現(xiàn)象

[wxf@host ~]$ for i in {1..6}; do netstat -s | grep -i listen; echo; sleep 1; done
    2436905 times the listen queue of a socket overflowed
    2436905 SYNs to LISTEN sockets ignored

    2436927 times the listen queue of a socket overflowed
    2436927 SYNs to LISTEN sockets ignored

    2436950 times the listen queue of a socket overflowed
    2436950 SYNs to LISTEN sockets ignored

    2436985 times the listen queue of a socket overflowed
    2436985 SYNs to LISTEN sockets ignored

    2436999 times the listen queue of a socket overflowed
    2436999 SYNs to LISTEN sockets ignored

    2437018 times the listen queue of a socket overflowed
    2437018 SYNs to LISTEN sockets ignored

從上面的結(jié)果可以看出济似,被丟棄的SYNs在不斷的增加

somaxconn為8192
客戶端沒有報錯
服務(wù)端

[wxy@host ~]$ for i in {1..6}; do netstat -s | grep -i listen; echo ;sleep 1; done
    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

    2439591 times the listen queue of a socket overflowed
    2439591 SYNs to LISTEN sockets ignored

可以看出矫废,這段時間內(nèi)沒有被丟棄的SYNs

驗證的結(jié)果和內(nèi)核代碼以及我們的預(yù)想是吻合的

**??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市砰蠢,隨后出現(xiàn)的幾起案子磷脯,更是在濱河造成了極大的恐慌,老刑警劉巖娩脾,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赵誓,死亡現(xiàn)場離奇詭異,居然都是意外死亡柿赊,警方通過查閱死者的電腦和手機俩功,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碰声,“玉大人诡蜓,你說我怎么就攤上這事∫忍簦” “怎么了蔓罚?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瞻颂。 經(jīng)常有香客問我豺谈,道長,這世上最難降的妖魔是什么贡这? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任茬末,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丽惭。我一直安慰自己击奶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布责掏。 她就那樣靜靜地躺著柜砾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪换衬。 梳的紋絲不亂的頭發(fā)上痰驱,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機與錄音冗疮,去河邊找鬼萄唇。 笑死檩帐,一個胖子當(dāng)著我的面吹牛术幔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播湃密,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼诅挑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泛源?” 一聲冷哼從身側(cè)響起拔妥,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎达箍,沒想到半個月后没龙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡缎玫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年硬纤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赃磨。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡筝家,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出邻辉,到底是詐尸還是另有隱情溪王,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布值骇,位于F島的核電站莹菱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吱瘩。R本人自食惡果不足惜芒珠,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搅裙。 院中可真熱鬧皱卓,春花似錦裹芝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掐禁,卻和暖如春怜械,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背傅事。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工缕允, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹭越。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓障本,卻偏偏與公主長得像,于是被迫代替她去往敵國和親响鹃。 傳聞我的和親對象是個殘疾皇子驾霜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)买置、netstat -nat 查看TCP各個狀態(tài)的數(shù)量2)粪糙、lso...
    北辰青閱讀 9,412評論 0 11
  • 18.1 引言 TCP是一個面向連接的協(xié)議。無論哪一方向另一方發(fā)送數(shù)據(jù)之前忿项,都必須先在雙方之間建立一條連接蓉冈。本章將...
    張芳濤閱讀 3,347評論 0 13
  • 隊列及參數(shù) server端的半連接隊列(syn隊列) 在三次握手協(xié)議中,服務(wù)器維護一個半連接隊列轩触,該隊列為每個客戶...
    go4it閱讀 8,245評論 4 17
  • 秋冬換季之時寞酿,想在淘寶上買些衣服,愛馬怕膛,原價居多熟嫩,十月中了,再有二十來天褐捻,不就雙11了麼掸茅,還是等雙11搶購吧。 前...
    從容小記閱讀 228評論 0 1
  • 學(xué)習(xí)回顧 Day1羅列 習(xí)慣養(yǎng)成是否成功的首要因素柠逞,就是這個習(xí)慣是不是你想要的昧狮、你為什么要養(yǎng)成這個習(xí)慣。也就是所謂...
    流光易閱讀 225評論 0 0