TCP连接数过多问题

    在一次生产上线后,发现使用的 8086 端口相关的 TCP 连接数竟然多大 6K+ ,有时候甚至会逼近 1w ,这个数量对于一个只是在内部使用的监控系统来说, 无论如何都是无法接受的, 于是开始一系列的排查过程. 本文记录了这个问题的主要解决过程,算是对这一次杀 bug 过程的一个总结.

问题描述

   使用命令

netstat -apn | grep 8086

    可以看到大量处于 TIME_WAIT状态的 tcp 连接

   使用命令

netstat -apn | grep 8086 | grep TIME_WAIT | wc -l

  进行计数, 会发现连接数会不断增加, 经过多次测试, 在公司环境中连接数至少都会达到 6k+. 这个问题必须要解决, 一方面是因为每条 tcp 连接都会占用内存, 另一方面系统的动态端口数也是有限的.

很明显这些连接几乎都处在 TIME_WAIT 状态,所以在继续往下走之前, 需要了解下 TIME_WAIT 这个关键字

TIME_WAIT

我们知道 一条 tcp 连接从开始到结束会经历多个状态, 换句话说, 可以把 一条 tcp 连接看成是一个 状态机. 这个状态图如下:

 

可以看到, 凡是主动进行关闭 tcp 连接的一方, 都会经过 TIME_WAIT 这个状态.接下来再经过 2MSL 的时间后内核再完全释放相应的文件描述符和端口. (顺便提一下, MSL 是最大分段寿命, 是一个 TCP 分段可以存在于互联网系统中的最大时间, 在 Linux 下可以用命令查看 MSL的数值:

cat /proc/sys/net/ipv4/tcp_fin_timeout

到这个地方可以推断出, 是 8086 端口主动关闭了 tcp 连接, 导致挤压了大量的处于 TIME_WAIT 状态下的连接在等待内核释放

问题处理

   为了解决大量TCP连接处于TIME_WAIT状态,需要对linux内核参数进行优化。编辑/etc/sysctl.conf文件,添加如下参数:

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 2000
 利用root口令执行sysctl -p
 
posted @ 2017-10-16 22:47  moonandstar08  阅读(14168)  评论(2编辑  收藏  举报