全連接隊列大小和半連接隊列大小如何設置?
全連接大小:全連接隊列大小取決於backlog 和somaxconn 的最小值,也就是 min(backlog,somaxconn)
- somaxconn 是Linux內核參數,默認128,可通過/proc/sys/net/core/somaxconn進行配置
- backlog是 listen(int sockfd,int backlog)函數中的參數backlog
半連接隊列大小:通過/proc/sys/net/ipv4/tcp_max_syn_backlog來設置
如何查看當前全連接隊列和半連接隊列的大小?
#查看半連接隊列
[root@server ~] netstat -natp | grep SYN_RECV | wc -l 233 #表示半連接狀態的TCP連接有233個
#查看全連接隊列
[root@server ~]# ss -lnt |grep 6080 State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 100 :::6080 :::*
- # -l 顯示正在Listener 的socket
- # -n 不解析服務名稱
- # -t 只顯示tcp
- # Recv-Q 完成三次握手並等待服務端 accept() 的 TCP 全連接總數,
- # Send-Q 全連接隊列大小
如何查看全連接半連接溢出?
netstat -s|egrep "SYNs to LISTEN" 直接查看半鏈接隊列是否有溢出,數字一直變大就是有溢出
netstat -s|grep overflowed 直接查看全鏈接隊列是否有溢出,數字一直變大就是有溢出
[root@server ~] netstat -s | egrep "listen|LISTEN"
7102 SYNs to LISTEN sockets ignored 表示半連接隊列溢出次數
7102 times the listen queue of a socket overflowed 全連接隊列溢出的次數
全連接半連接溢出后如何處理?
當全連接隊列已滿就會根據tcp_abort_on_overflow策略進行處理。Linux 可通過 /proc/sys/net/ipv4/tcp_abort_on_overflow 進行配置。
- 當tcp_abort_on_overflow=0,服務accept 隊列滿了,客戶端發來ack,服務端直接丟棄該ACK,此時服務端處於【syn_rcvd】的狀態,客戶端處於【established】的狀態。在該狀態下會有一個定時器重傳服務端 SYN/ACK 給客戶端(不超過 /proc/sys/net/ipv4/tcp_synack_retries 指定的次數,Linux下默認5)。超過后,服務器不在重傳,后續也不會有任何動作。如果此時客戶端發送數據過來,服務端會返回RST。(這也就是我們的異常原因了)
- 當tcp_abort_on_overflow=1,服務端accept隊列滿了,客戶端發來ack,服務端直接返回RST通知client,表示廢掉這個握手過程和這個連接,client會報connection reset by peer。
如果半連接隊列滿了,並且沒有開啟 tcp_syncookies,則會丟棄;
net.ipv4.tcp_syncookies = 1
表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊,默認為0,表示關閉;
tcp_syncookies是一個開關,是否打開SYN Cookie功能,該功能可以防止部分SYN攻擊。tcp_synack_retries和tcp_syn_retries定義SYN的重試次數。
connection time out
)錯誤。但是,當Server端開啟了syncookies=1,那么SYN半連接隊列就沒有邏輯上的最大值了,並且/proc/sys/net/ipv4/tcp_max_syn_backlog設置的值也會被忽略。