TIME_WAIT过多导致负载爆表优化方法

Eave 2017.04.04 16:26

最近参与的项目每日大概有300w的请求量,8核的服务器负载竟然最高可以跑到20,给跪了

查看TCP状态:

netstat -n | awk "/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}"

TIME_WAIT 有5000,ESTABLISHED有500左右

摸不着头脑,随意百度了下TIME_WAIT过多

发现TIME_WAIT状态的socket一般需要等到2msl时间后,socket才会被回收,TIME_WAIT过多会影响服务器性能

解决TIME_WAIT过多的方法

修改(添加)系统内核参数:/etc/sysctl.conf

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

# 开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击
net.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

使新增参数生效:

sysctl -p

之后有搜寻了一些资料,最后找到一份新浪内部优化资料

里面介绍TIME_WAIT分被动连接和主动连接,也给出了实践优化结论

被动连接情况下:

实际演示:

1、使用系统默认配置

2、增大tcp_max_tw_buckets

3、缩短TIME_WAIT超时时间

4、将tcp_max_tw_buckets 设置为0

结论:

1、被动连接情况下,TIME_WAIT对性能的影响有限

2、不建议增大tcp_max_tw_buckets,因为这 会导致Linux性能的小量衰减

3、人工将TIME_WAIT超时时间调短后,不会给性能带来明显提升,在某些情况下也许会起到反作用

4、tcp_max_tw_buckets设置为0后,可轻微降低CPU利用率

主动连接情况下:

实际演示:

1、使用系统默认配置(net.ipv4.tcp_tw_reuse和tcp_tw_recycle都设置为0

2、Sysctl 设置net.ipv4.tcp_tw_reuse=1后

3、sysctl设置net.ipv4.tcp_tw_recycle=1后

4、sysctl设置net.ipv4.tcp_timestamps=0后

结论:

1、主动连接情况下,TIME_WAIT对性能的影响很大

2、net.ipv4.tcp_tw_reuse和tcp_tw_recycle都设置为0时,在本地端口耗尽后负载会很高

3、net.ipv4.tcp_tw_reuse=1和net.ipv4.tcp_tw_recycle=1 配置生效的前提条件是:--TCP连接的两端都要启用TCP的时间戳选项。Windows客户端默认不启用时间戳选项

4、net.ipv4.tcp_tw_reuse设置为1后,会降低本地端口耗尽出现的概率,从而降低负载

5、net.ipv4.tcp_tw_recycle设置为1后,会加速TIME_WAIT的回收,从而显著降低系统中TIME_WAIT状态的socket数量

6、对于主动连接较多的服务器建议通过调整sysctl的net.ipv4.ip_local_port_range来增大本地端口范围,以进一步降低端口耗尽出现的概率

看到现在,还是知其然不知其所以然的状态,看来要恶补下一些理论知识了~