HelloBug0

1 TCP 连接队列

三次握手中: 服务端收到客户端的 SYN 包,将 SYN 包放入 TCP 的 SYN 队列(半连接队列) 服务端收到客户端的 ACK 包,将 ACK 包放入 TCP 的 ACCEPT 队列(全连接队列)

2 连接队列长度如何确定?

3 半连接队列满了怎么办?

如果 TCP 的 SYNC 队列(半连接队列)满时,内核参数 net.ipv4.tcp_syncookie 决定操作系统的行为(操作系统配置文件中配置,如CentOS7系统,配置文件为 /etc/sysctl.conf)。

net.ipv4.tcp_syncookie = 0(关闭)/1(启用,默认)/2(无条件使用)

4 全连接队列满了怎么办?

如果 TCP 的 ACCEPT 队列(全连接队列)满时,内核参数 net.ipv4.tcp_abort_on_overflow 决定操作系统的行为(操作系统配置文件中配置该参数,如CentOS7系统,配置文件为 /etc/sysctl.conf)。

net.ipv4.tcp_abort_on_overflow = 0(丢包,默认)/1(重置)

5 如何查看进程队列长度?

查看当前以及最大 ACCEPT 队列(全连接队列)长度

[root@localhost ~]# ss -lnt
State      Recv-Q Send-Q     Peer Address:Port       Local Address:Port                                                
LISTEN       0        511              *:*                        127.0.0.1:6379                                                            
LISTEN       0        128              *:*                             *:22                         

其中 Recv-Q 表示当前 ACCEPT 队列(全连接队列)长度,Send-Q 表示最大 ACCEPT 队列(全连接队列)长度。

没有直接的命令可以查看当前 SYN 队列(半连接队列)的长度,可以通过查看当前系统中 Socket 处于 SYN_RECV 状态的数量来间接评估,可以在以下命令中过滤服务端的监听端口,统计某个服务端的 SYN_RECV 状态的 Socket 数量。

netstat -ant | grep SYN_RECV | wc -l

注意每个监听网络端口的服务端程序,半连接和全连接队列是独享的。

6 如何查看连接队列是否溢出?

判断全连接队列是否溢出

netstat -s | grep "overflowed"
times the listen queue of a socket overflowed 3454

如果最后面的数字不断增长,表示全连接队列发生了溢出。

判断半连接队列是否溢出

netstat -s \| grep -i "SYNs to LISTEN sockets dropped"
SYNs to LISTEN sockets dropped 289

如果最后面的数字不断增长,表示半连接队列可能发生了溢出,但这个统计不完全可靠,因为全连接队列满了,这个数字也会增加。