2639  
查询码:00000037
tomcat服务器tcp连接出现大量ESTABLISHED连接导致前端访问502解决方法
作者: wyasw 于 2020年03月29日 发布在分类 / Linux / web服务 下,并于 2020年03月29日 编辑
web

tomcat服务器tcp连接出现大量ESTABLISHED连接导致前端访问502解决方法

1.1 TCP状态转移要点

TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不 会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得 注意的状态有两个:CLOSE_WAITTIME_WAIT 

1LISTENING状态

FTP服务启动后首先处于侦听(LISTENING)状态。

2ESTABLISHED状态

ESTABLISHED的意思是建立连接。表示两台机器正在通信。

3CLOSE_WAIT

    对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

4TIME_WAIT

    我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAITTCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。

    目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socketLINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

5SYN_SENT状态

SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为 ESTABLISHED,此时SYN_SENT状态非常短暂。但如果发现SYN_SENT非常多且在向不同的机器发出,那你的机器可能中了冲击波或震荡波 之类的病毒了。这类病毒为了感染别的计算机,它就要扫描别的计算机,在扫描的过程中对每个要扫描的计算机都要发出了同步请求,这也是出现许多 SYN_SENT的原因。

根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2MSL(Max Segment Lifetime),Windows下默认为4分钟,240,TIME_WAIT状态下的socket不能被回收使用具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAITTCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.

1.2 TCP协议中有TIME_WAIT这个状态

主要有两个原因

1。防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)

2。可靠的关闭TCP连接。在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发

fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 

1.3 查看系统TCP连接资源命令

查看网络连接数:

# netstat -an |grep xx |wc -l        查看某个/特定ip的连接数

# netstat -an |grep TIME_WAIT|wc -l    查看连接数等待time_wait状态连接数

# netstat -an |grep ESTABLISHED |wc -l    查看建立稳定连接数量

查看不同状态的连接数数量

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

  LISTEN t 8

  ESTABLISHED t 2300

  FIN_WAIT1 t 2

  TIME_WAIT t 6000

状态:描述

CLOSED:无连接是活动的或正在进行

LISTEN:服务器在等待进入呼叫

SYN_RECV:一个连接请求已经到达,等待确认

SYN_SENT:应用已经开始,打开一个连接

ESTABLISHED:正常数据传输状态

FIN_WAIT1:应用说它已经完成

FIN_WAIT2:另一边已同意释放

ITMED_WAIT:等待所有分组死掉

CLOSING:两边同时尝试关闭

TIME_WAIT表示处理完毕,等待超时结束的请求数。

LAST_ACK:等待所有分组死掉

查看每个ip跟服务器建立的连接数

# netstat -nat|grep "tcp"|awk ' {print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn

      112 172.16.12.111

      2 172.16.23.253

      1 172.16.15.110

      1 172.16.15.106

      1 172.16.15.105

PS:正则解析:显示第5列,-F : 以:分割,显示列,sort 排序,uniq -c统计排序过程中的重复行,sort -rn 按纯数字进行逆序排序)

查看每个ip建立的ESTABLISHED/TIME_OUT状态的连接数

# netstat -nat|grep ESTABLISHED|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn

    119 172.16.12.111

      3 10.1.160.103

      2 172.16.23.253

      2 113.31.138.48

      1 172.16.15.110

      1 172.16.15.106

1.4 怎么解决大量Time_Wait

通过调整内核参数:

vim /etc/sysctl.conf

#编辑文件,加入以下内容:

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 30

#然后执行 /sbin/sysctl -p 让参数生效。

配置说明:

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

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

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

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

如果以上配置调优后性能还不理想,可继续修改一下配置:

vi /etc/sysctl.conf

net.ipv4.tcp_keepalive_time = 1200

#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。

net.ipv4.ip_local_port_range = 1024 65000

#表示用于向外连接的端口范围。缺省情况下很小:3276861000,改为102465000

net.ipv4.tcp_max_syn_backlog = 8192

#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

net.ipv4.tcp_max_tw_buckets = 5000

#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。

默认为180000,改为5000。对于ApacheNginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量。

但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

调优完毕,再压一下看看效果吧。

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

1.5 怎么解决请求结束后依然存在大量ESTABLISHED没有被释放

初步推断是tomcat服务器回收session时出了问题,这个一般都跟服务器的Timeout设置有联系。

查看tomcat的配置文件 server.xml

<Connector port="8080" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443" URIEncoding="UTF-8" />

*****

检查配置得出20000毫秒的时候acceptCount="100" ,明显不合理,最大连接数也太小了吧。

所以进一步优化:

connectionTimeout="20000" 改为 connectionTimeout="2000"

acceptCount="100"改为acceptCount="2000"

优化完毕,继续观察,发现 ESTABLISHED再也没有超过500



 推荐知识

 历史版本

修改日期 修改人 备注
2020-03-29 21:30:25[当前版本] wyasw 创建版本

  目录
    文艺知识分享平台 -V 4.9.5 -wcp
    京公网安备100012199188号 京ICP备2021030911号