java 服务大量外部连接导至异常
相信很多小伙伴都碰到过一个问题,服务运行过程中,产生大量的未关闭的TCP链接,导至服务不可用直至服务异常。
该如何定位、排查这些未关闭的链接?
之前碰到过这个问题,解决了,今天有小伙伴又聊到这个问题,就将这个问题复现出来,如果有人看到这个问题,可以帮助解决这个问题。
复现
通过 jmeter 复制问题,由于问题已经被解决,但是可以通过 jmeter 100%复现该问题。
复现流程:
- 通过 jmeter 发起 http 请求,并且不释放请求。
- 停止 jmeter 后查看状态
java.net.NoRouteToHostException: Can't assign requested address (Address not available)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
报的错是Can't assign requested address
,推测是调用IP地址问题。
排查
如果是IP地址的问题那么验证一下是不是IP地址的连接是不是有问题。
排查网络问题,第一个想到netstat
。
jmeter发起大量请求
命令:
netstat -nt | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'
结果如下:
CLOSE_WAIT t 1
ESTABLISHED t 50
TIME_WAIT t 13006
TIME_WAIT t 是 13006 这么多的连接。
TIME_WAIT表示处理完毕,等待超时结束的请求数。
这个时候外部再调接口就会报错。
停止jmeter请求
netstat -nt | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'
结果如下:
CLOSE_WAIT t 1
ESTABLISHED t 48
FIN_WAIT1 t 1
TIME_WAIT t 40
这个时候 TIME_WAIT 只有 40,外部调用接口,不报错。
解决
这种问题原因是因为有大量的外部请求进来后不释放,正常业务调用没有问题,但是如果遇到恶意的请求就会有问题。
解决:设置 http 请求超时时间,不让请求无限的等待下去,就可以避免这个问题。