上图就是tcp建联的三次握手过程。
半连接队列:保存处于SYN_RCVD状态的socket的队列。
全连接队列:保存处于ESTABLISHED状态的socket的队列。(已经完成三次握手,Server还未调用accept()函数将socket交由应用层处理)
全连接对列最大长度计算公式:
min(net.core.somaxconn, backlog) |
ps:
查看全连接队列长度:
注意:连接状态不同,Recv-Q和Send-Q的含义不相同。
当连接在LISTEN状态下时,Recv-Q表示当前全连接队列的长度, Send-Q表示最大的全连接队列长度
# ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 32768 *:9999 *:* LISTEN 0 100 *:8080 *:* LISTEN 0 128 *:18822 *:* LISTEN 0 50 *:7879 *:* |
当连接在非LISTEN状态下时,Recv-Q表示已收到但未被应用进程读取的字节数;Send-Q表示的是已发送但未收到确认的字节数。
# ss -lnt | grep 80 State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 51 128 *:80 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::58803 :::* # ss -lnt | grep 80 LISTEN 129 128 *:80 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::58803 :::* |
查看全连接队列(accept queue)溢出的统计信息:
# netstat -s | grep overflowed 172308 times the listen queue of a socket overflowed # netstat -s | grep overflowed 175641 times the listen queue of a socket overflowed |
注意:“172308 ”,"175641 "是个累计值,常用后一次与前一次的取差值,若为正,则表示队列溢出。
全连接队列满了,怎么办?
当全连接队列满了,linux默认是丢弃连接,还可以通过/proc/sys/net/ipv4/tcp_abort_on_overflow值来控制。
若为0,则丢弃连接(默认)
若为1,则server 发送一个 reset 包给 client
如何调整全连接队列大小?
因为全连接队列大小=min(/proc/sys/net/core/somaxconn,backlog)。所以调整全连接队列大小时,两个都需要调。
比如:nginx默认backlog是511,linux 3.10.0内核/proc/sys/net/core/somaxconn 默认是128。
调整实例:
echo 2000 > /proc/sys/net/core/somaxconn | |
[root@rocketmq-server ipv4]# cat /etc/nginx/nginx.conf | grep listen listen 80 default_server backlog=1500; | |
[root@rocketmq-server ipv4]# ss -lnt | grep 80 LISTEN 0 1500 *:80 *:* | 所以min(2000,1500)全连接队列变成了1500. |
半连接队列最大长度计算公式:
很多博客说SYN队列的最大长度是由/proc/sys/net/ipv4/tcp_max_syn_backlog参数指定的。实际上,只有当linux内核版本早于2.6.20时,SYN队列才等于backlog的大小。
实际上:SYN队列的最大长度由三个参数指定:
查看当前半连接队列长度(只能粗略估计,SYN-RECV的数量少于实际半连接队列的长度):
#ss -antp | grep SYN-RECV | wc -l |
查看半连接队列(syn queue)溢出的统计信息:
# netstat -s | grep dropped 166 SYNs to LISTEN sockets dropped |
注意:“166”是个累计值,常用后一次与前一次的取差值,若为正,则表示队列溢出。
半连接队列满了,怎么办?
若半连接队列满了,根据不同情况,对连接可能有不同的处理方式,可能是直接丢弃,也可能是发送reset包
分如下几种情况:
"max_syn_backlog >> 2" :相当于右移2位,即max_syn_backlog / (2*2)
参考文章:
4.4 TCP 半连接队列和全连接队列 | 小林coding
TCP SYN Queue and Accept Queue Overflow Explained - Alibaba Cloud Community