TCP的狀態轉換及生產問題實操

2021-09-11 14:07:00 字數 3306 閱讀 3988

前文介紹了tcp協議主要的流程,包括建立連線、傳輸資料和斷開連線。如果大家認真閱讀了附圖,應該可以看到在各個流程中套接字的狀態是在不斷變化的,不同的狀態標識了套集字所處的階段。

如圖1是tcp乙個完整的狀態轉換圖,圖中包含了套接字的所有狀態,以及發生狀態轉變的觸發條件。可能會有人問,了解這些狀態有什麼用呢?我們平時程式設計又用不到。

圖1 tcp狀態轉換圖

為了說明上述問題,我們從3個角度進行解釋,分別是各種狀態的含義、在系統層面如何查詢狀態和在實際生產中的應用。

一、各種狀態的含義

在回答問題之前我們先具體了解一下各個狀態的含義。

二、狀態的監控方法

前文已經有提及,可以通過netstat命令檢視tcp連線的狀態。圖2是乙個簡單的例子,執行該命令的時候不帶任何引數。

圖2 netstat執行結果

由上圖可以看出,通過netstat可以看到每個tcp連線和udp的狀態和詳細的ip位址等資訊。該命令有很多引數,通過不同的引數可以得到我們想要的內容。下面我們舉幾個具體的例子。

1. 顯示所有埠資訊

可以通過-a引數列出所有埠資訊,而且可以附帶-t只列出tcp協議的,或者-u只列出udp協議的埠資訊。

[root@itworld123~]# netstat -a # 列出所有埠 

[root@itworld123~]# netstat -at # 列出所有tcp埠 

[root@itworld123~]# netstat -au # 列出所有udp埠 

2. 顯示所有監聽狀態的套接字

可以通過-l引數列出所有處於監聽狀態的套接字。當然也可以結合-t或者-u引數獲取想要的資訊。如下是獲取tcp處於監聽狀態的套接字列表:

圖3 監聽狀態列表

3. 檢視服務狀態

可以檢視具體的服務的監聽和套接字等狀態。例如下面命令用於檢視ssh服務的狀態:

圖3 ssh狀態結果

4. 其它

當然,也可以通過shell指令碼實現複雜的查詢,比如下面用於統計established狀態的數量。

netstat -n | awk '/^tcp/  end ' 

三、實際生產環境的意義

前面囉嗦了一大堆,我們回到正題,了解這些狀態到底有什麼用呢?我們知道linux作業系統對檔案控制代碼的總量是有限制的,套接字也屬於檔案控制代碼,因此也是有限制的。了解套接字的狀態有助於我們了解伺服器是否有隱患或者效能瓶頸。

說到這,可能有的同學還是不明白,我們舉個簡單的例子。假設一台伺服器最多有6萬個控制代碼,如果由於某種業務場景,在伺服器端出現大量的time_wait,此時這些套接字是無法馬上釋放,也就是無法馬上被重複使用,但仍然占用6萬控制代碼的名額。這塊,隨著時間的推移,可能會耗盡所有控制代碼,從而導致有新的連線請求是伺服器端無法響應的問題。

為了讓大家更形象的理解這些狀態在實際生產中的意義,我們舉幾個實際生產中遇到問題的例子。

1. 伺服器端大量time_wait

(1) 現象描述

某物件儲存服務,在監控系統發現有大量的time_wait。經確認該伺服器是一台新上架接入的伺服器。經反覆確認,具備相同功能的同集群的其它伺服器工作都正常,並不存在大量time_wait的情況。

(2) 問題分析

結合協議我們知道主動關閉方會處於該狀態,而且time_wait狀態下的tcp連線會等待2*msl。因此我們檢視系統配置cat /proc/sys/net/ipv4/tcp_fin_timeout,發現是預設值。因此,確定是等待時間太長,導致套接字無法被利用所致。

(3) 問題解決

net.ipv4.tcp_syncookies = 1 

net.ipv4.tcp_tw_reuse = 1 

net.ipv4.tcp_tw_recycle = 1 

net.ipv4.tcp_fin_timeout = 30 

然後執行/sbin/sysctl -p讓引數生效。

上述內容的含義具體如下:

2. 伺服器端大量established

(1) 問題描述

某tomcat伺服器出現大量established連線。

(2) 問題分析

根據協議狀態轉換情況,初步推斷是tomcat伺服器**session時出了問題,這個一般都跟伺服器的timeout設定有聯絡。

檢視tomcat的配置檔案 server.xml

connectiontimeout="20000" 

redirectport="8443" uriencoding="utf-8" /> 

***** 

我們重點關注一下connectiontimeout,這個配置導致建立乙個socket連線後,如果一直沒有收到客戶端的fin,也沒有資料過來,那麼此連線也必須等到10s後,才能被超時釋放。由於伺服器併發量大,而該超時時間有長,導致連線釋放嚴重滯後,因此出現大量的established連線。

(3) 問題解決

分析上述問題後,我們有針對性的作出如下修改。

connectiontimeout="20000" 改為 connectiontimeout="100" 

acceptcount="100"改為acceptcount="5000" 

修改後問題解決。

實際的例子還很多,但萬變不離其宗,需要我們熟悉tcp協議和狀態轉換,這樣在實際生產中遇到問題就可以有理有據的進行分析,然後輕鬆解決。

TCP狀態轉換的理解

虛線為伺服器狀態轉換 實現為客戶端狀態轉換 正常tcp連線中客戶端與服務端狀態轉換 伺服器端狀態 1.listen 服務啟動後處於監聽狀態 2.syn recv 收到乙個連線請求,尚未確認 3.established 連線建立,正常資料傳輸狀態 4.close wait 被動關閉 收到對方關閉請求,...

對TCP狀態轉換的理解

listen 這個也是非常容易理解的乙個狀態,表示伺服器端的某個socket處於監聽狀態,可以接受連線了。syn rcvd 這個狀態表示接收到了syn報文,在正常情況下,這個狀態是伺服器端的socket在建立tcp連線時的三次握手會話過程中的乙個中間狀態,很短暫,基本上用netstat你是很難看到這...

程序的狀態及轉換

目錄 引起程序狀態轉換的具體原因如下 執行態 阻塞態 等待使用資源 如等待外設傳輸 等待人工干預。阻塞態 就緒態 資源得到滿足 如外設傳輸結束 人工干預完成。執行態 就緒態 執行時間片到 出現有更高優先權程序。就緒態 執行態 cpu 空閒時選擇乙個就緒程序。五態模型在三態模型的基礎上增加了建立態 n...