TCP(五) -- 連接隊列

一:摘要概述

客戶端與服務端創建連接的過程稱之爲三次握手,三次握手過程中狀態的變更以及數據信息的交互在系列文章TCP(二) – 三次握手中已經詳細闡述。但是是否思考過一個問題,服務端如何處理SYN、ACK後的連接

二:連接隊列

在這裏插入圖片描述

  • syns queue:半連接隊列,存儲SYN後的連接
  • accept queue:全連接隊列,存儲ACK後的連接

當客戶端Client發送SYN包給服務端時,服務端會將連接信息存儲到半連接隊列,服務端回覆SYN+ACK。客戶端獲取SYN+ACK數據包處理並回復ACK,服務端獲取到客戶端ACK後由半連接隊列中取出連接信息處理存儲到全連接隊列。全連接隊列中的連接就可以等待應用程序使用取出

三:連接控制

連接隊列大小肯定不可能無限大,控制連接隊列大小就是需要關注的一個核心問題,這關係着應用可承載壓力。兩個核心的數值如下:

  • backlog:程序控制的參數,指定連接隊列大小。Java默認50、Nginx/Redis等默認511
  • somaxconn:系統參數,CentOS默認數值128

backlog調用函數accept()時可以指定,但是系統不會直接選取該值作爲連接隊列大小。而是會根據系統參數somaxconn結合考慮。其選取標準爲min(backlog,somaxconn),如下圖所示,通過Tomcat發佈的應用,其中Tomcat設置連接數量參數爲800,但是最後查詢顯示也僅僅是128。128是系統參數somaxconn的默認值,修改路徑爲/pro/sys/net/core/somaxconn
在這裏插入圖片描述
在這裏插入圖片描述

四:連接策略

當連接隊列充滿時有新的連接進入,這時候服務端會如何進行處理?這個策略由參數/proc/sys/net/ipv4/tcp_abort_on_overflow控制。其默認值爲0,具體的策略如下描述:

  • 0:全連接隊列溢出,服務端Server扔掉客戶端Client發送的數據包信息
  • 1:全連接隊列溢出,服務端發送RST包到客戶端Client強制斷開連接

當參數設定爲1的時候服務端會發送RST包到客戶端,所以對於客戶端來講至少是知道連接失敗的信息。但是當參數值設置爲0的時候客戶端並不知道連接失敗,Client判斷爲連接成功處於ESTABLISHED狀態會向服務端發送數據,如下圖所示:
在這裏插入圖片描述
上圖所示當客戶端認定連接狀態處於正常情況下發送數據服務端會丟棄該數據包不做任何處理,這時候客戶端會進行重
試傳輸,重試的次數由參數/proc/sys/net/ipv4/tcp_retries2控制。具體的超時重傳策略將會在後續文章中進行解釋。對於客戶端的操作已經比較清晰的情況下可以思考服務端的操作,服務端此時認定連接並未成功,操作如下圖所示:
在這裏插入圖片描述
服務端會重走三次握手的第二步,向客戶端傳輸SYN+ACK

五:泄漏排查

進行壓測的過程中如果遇到間斷性連接獲取不到,亦或是出現連接無響應的情況。但是查看機器的CPU等數據參數狀況正常,壓力還是上不去,注意了這時候你就需要排查連接隊列是否存在溢出的情況

[root@bogon ~]# netstat -s | egrep "listen|LISTEN" 
    4972416 times the listen queue of a socket overflowed
    4972416 SYNs to LISTEN sockets ignored

上述命令可以查看到服務器連接隊列情況,如果該數據持續上升就可以印證存在隊列溢出的情況,就需要調整相關參數

[root@bogon ~]# ss -s
Total: 4759 (kernel 4831)
TCP:   4533 (estab 4087, closed 204, orphaned 6, synrecv 0, timewait 32/0), ports 2460

Transport Total     IP        IPv6
*         4831      -         -        
RAW       0         0         0        
UDP       8         5         3        
TCP       4329      12        4317     
INET      4337      17        4320     
FRAG      0         0         0

使用ss -s命令可以查看到具體的服務器上連接信息,當然ss命令還可以查看很多內容。常用參數作用如下:

序列編碼 參數名稱 參數作用
1 s 查詢概要情況
2 a 顯示所有套接字
3 l LISTEN 狀態
4 t 查詢TCP連接
5 u 查詢UDP連接
6 n 不要翻譯服務器名稱
[root@bogon ~]# ss -alnt
State       Recv-Q Send-Q                Local Address:Port           Peer Address:Port 
LISTEN      0      100                   :::15345                     :::*     
LISTEN      0      1                     ::ffff:127.0.0.1:15217       :::* 

其中Send-Q參數表示全連接隊列的大小,Recv-Q表示全連接隊列使用的數量

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章