netstat和tcp

使用 netstat

  netstat 命令是 linux 下一个很是有用的命令,顾名思义,其做用是查询当前的网络状态。
  以最经常使用的查询 TCP 链接状态为例,在 Shell 里运行如下命令:linux

netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c

  你会看到当前全部 TCP 链接的状态计数:程序员

屏幕快照

  有更高追求的程序员,可能会想吧结果美化一下。好比,使用下面的命令:vim

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

  你会获得以下的结果:服务器

屏幕快照

  上述两个命令的结果不一样,是由于我运行命令的时机不一样,他们的意义是同样的,仅仅只有格式的区别。cookie

分析 TCP 状态

  这些状态有什么含义呢?咱们首先看一下 TCP 状态转换图:网络

TCP 状态转换图

TCP 状态转换图并发

  总结各状态大体意义以下:socket

  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 报文。tcp

  其中 SYN_RECVESTABLISHEDTIME_WAIT 是对咱们比较有意义的几个状态。优化

SYN_RECV

  表示正在等待处理的请求数。SYN_RECV 过多或居高不下,能够理解为服务器并不能及时处理全部的请求。这时要考虑进行效率优化,或增长更多的服务器;

ESTABLISHED

  表示正在进行数据传输的请求数。一般与在线人数和并发相关,能够做为服务器负载能力的一项指标。

TIME_WAIT

  表示处理完毕,等待超时结束的请求数。若 TIME_WAIT 过多,可调整内核参数进行优化,若仍无效,则需注意是否遭到了恶意攻击。如有大量的 SYN_RECEIVEDTIME_WAITFIN_WAIT_1 等状态存在,而 ESTABLISHED 不多,则可初步判断存在 DDOS 攻击。

关于 TIME_WAIT

  主动关闭的一方在发送最后一个 ACK 报文后,就会进入 TIME_WAIT 状态,停留 2MSL(max segment lifetime)。

  TCP/IP 协议中如此设计,主要有两个缘由:

  1. 防止上一次链接中的包,迷路后从新出现,影响新链接。 通过 2MSL,上一次链接中全部的重复包都会消失。

  2. 可靠的关闭 TCP 链接。 主动关闭方发送的最后一个 ACK(FIN) 报文,有可能丢失,这时被动方会从新发送 FIN 报文, 若是这时主动方处于 CLOSED 状态 ,就会响应 RST 报文而不是 ACK 报文。因此主动方要处于 TIME_WAIT 状态,而不能是 CLOSED

  TIME_WAIT 并不会占用太多资源,除非受到恶意攻击。

优化 TIME_WAIT

  经过调整内核参数,能够缓解 TIME_WAIT 过多的状况。
  首先打开配置文件 vim /etc/sysctl.conf,修改如下配置:

# 表示开启 SYN cookies。当出现 SYN 等待队列溢出时,启用 cookies 来处理,可防范少许 SYN 攻击,默认为 0,表示关闭;
net.ipv4.tcp_syncookies = 1

# 表示开启重用。容许将 TIME-WAIT sockets 从新用于新的 TCP 链接,默认为 0,表示关闭;
net.ipv4.tcp_tw_reuse = 1

# 表示开启 TCP 链接中 TIME-WAIT sockets 的快速回收,默认为 0,表示关闭;
net.ipv4.tcp_tw_recycle = 1

# 修改系統默认的 TIMEOUT 时间
net.ipv4.tcp_fin_timeout = 1

  而后执行以命令 /sbin/sysctl -p 让参数生效。

相关文章
相关标签/搜索