TIME_WAIT过多导致负载爆表优化方法
最近参与的项目每日大概有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来增大本地端口范围,以进一步降低端口耗尽出现的概率
看到现在,还是知其然不知其所以然的状态,看来要恶补下一些理论知识了~