使用 netstat
netstat
命令是 linux 下一个非常有用的命令,顾名思义,其作用是查询当前的网络状态。
以最常用的查询 TCP 连接状态为例,在 Shell 里运行以下命令:
|
|
你会看到当前所有 TCP 连接的状态计数:
有更高追求的程序员,可能会想吧结果美化一下。比如,使用下面的命令:
|
|
你会得到如下的结果:
上述两个命令的结果不同,是因为我运行命令的时机不同,他们的意义是一样的,仅仅只有格式的区别。
分析 TCP 状态
这些状态有什么含义呢?我们首先看一下 TCP 状态转换图:
总结各状态大致意义如下:
CLOSED
初始状态。
LISTEN
服务端处于监听状态,可以接受连接。
SYN_SENT
客户端连接并发送 SYN 报文,进入 SYN_SENT
状态,等待服务端确认。
SYN_RCVD
服务端接受到了 SYN 报文,当收到客户端的 ACK 报文后,会进入到 ESTABLISHED
状态。
ESTABLISHED
连接已经建立,进入数据传输状态。
FIN_WAIT_1
建立连接后,其中一方请求终止连接,等待对方的 FIN 报文。
FIN_WAIT_2
半连接,有一方要求关闭连接,但另外还告诉对方,我还有数据需要传输,稍后再关闭连接。
TIME_WAIT
收到了对方的 FIN 报文,并发送出了 ACK 报文,2MSL 后即可回到 CLOSED
可用状态。
CLOSE_WAIT
等待关闭。
CLOSING
当发送 FIN 报文后,并未收到对方的 ACK 报文,却收到了 FIN 报文,表示双方都正在关闭连接。
LAST_ACK
被动关闭一方在发送 FIN 报文后,最后等待对方的 ACK 报文。
其中 SYN_RECV
、ESTABLISHED
、TIME_WAIT
是对我们比较有意义的几个状态。
SYN_RECV
表示正在等待处理的请求数。SYN_RECV
过多或居高不下,可以理解为服务器并不能及时处理所有的请求。这时要考虑进行效率优化,或增加更多的服务器;
ESTABLISHED
表示正在进行数据传输的请求数。通常与在线人数和并发相关,可以作为服务器负载能力的一项指标。
TIME_WAIT
表示处理完毕,等待超时结束的请求数。若 TIME_WAIT
过多,可调整内核参数进行优化,若仍无效,则需注意是否遭到了恶意攻击。若有大量的 SYN_RECEIVED
、TIME_WAIT
、FIN_WAIT_1
等状态存在,而 ESTABLISHED
很少,则可初步判断存在 DDOS 攻击。
关于 TIME_WAIT
主动关闭的一方在发送最后一个 ACK 报文后,就会进入 TIME_WAIT
状态,停留 2MSL(max segment lifetime)。
TCP/IP 协议中如此设计,主要有两个原因:
防止上一次连接中的包,迷路后重新出现,影响新连接。 经过 2MSL,上一次连接中所有的重复包都会消失。
可靠的关闭 TCP 连接。 主动关闭方发送的最后一个 ACK(FIN) 报文,有可能丢失,这时被动方会重新发送 FIN 报文, 如果这时主动方处于
CLOSED
状态 ,就会响应 RST 报文而不是 ACK 报文。所以主动方要处于TIME_WAIT
状态,而不能是CLOSED
。
TIME_WAIT
并不会占用太多资源,除非受到恶意攻击。
优化 TIME_WAIT
通过调整内核参数,可以缓解 TIME_WAIT
过多的情况。
首先打开配置文件 vim /etc/sysctl.conf
,修改以下配置:
|
|
然后执行以命令 /sbin/sysctl -p
让参数生效。