TCP 隊列溢出了

一、TCP 隊列

1、syns queue:半連接隊列

TCP 三次握手(參考:TCP建立連接之三次握手),第一步,服務端接收到客戶端發送的 syn 消息後,將連接資訊放入 syns queue,此時,雙方連接尚未建立,稱之為半連接。

2、accept queue:全連接隊列

TCP 三次握手,第三步,客戶端接收到服務端發送的 syn + ack 消息後,向服務端發送 ack 消息,服務端接收到此消息後,將連接資訊從 syns queue 拿出,放入 accept queue,此時,經過三次握手,連接已經建立,稱之為全連接。

二、隊列溢出

既然是隊列,那就會存在隊列被填滿的情況,我們稱之為隊列溢出。

1、syns queue 滿

假如某一時間段內,有大量的 syn 請求連接資訊到達,如果後續連接建立處理不及時,或者有客戶端方面惡意不處理後續連接,那麼就會快速佔滿 syns queue,從而導致無法建立新的連接。

2、accept queue 滿

完成三次握手,則會觸發連接資訊的隊列轉移,假如此時,accept queue 隊列滿,則會導致新建立的連接得不到維護保持,系統會根據設定的策略(tcp_abort_on_overflow)進行連接的直接拋棄(0)或者發送 RST 消息給客戶端終止連接(1)(Connection reset by peer)。

3、查看隊列溢出

命令:netstat -s | egrep “listen|LISTEN”

結果:

全連接隊列溢出次數:
6 times the listen queue of a socket overflowed

半連接隊列溢出次數:
6 SYNs to LISTEN sockets dropped

4、查看隊列使用情況

命令:ss -lnt

結果:

State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0         128              *:22                   *:*
LISTEN 0          50             *:9090                 *:*

Send-Q:監聽埠上全連接隊列最大大小

Recv-Q:全連接隊列當前使用量

三、關於連接錯誤

connection reset:已關閉的連接上執行讀操作觸發。

connection reset by peer:已關閉的連接上執行寫操作觸發。

四、關於 RST 消息

連接重置消息,用於連接的【異常關閉】。

下面簡單羅列集中可能觸發 RST 連接關閉的情景:

1、服務端接收到自身不存在埠的連接請求

2、主動使用 RST 關閉,替代正常的四次揮手 FIN 消息關閉(參考:TCP連接性能指標之TCP關閉過程(四次揮手)),主要用於特殊優化提升效率使用。

3、客戶端或者服務端異常,無法繼續正常的連接處理,發送 RST 終止連接操作。

4、處理 TCP 遊離包資訊。

5、長期未收到對方確認報文,經過一定時間或者重傳嘗試後,發送 RST 終止連接。