相信很多小伙伴都碰到过一个问题,服务运行过程中,产生大量的未关闭的TCP链接,导至服务不可用直至服务异常。
该如何定位、排查这些未关闭的链接?
之前碰到过这个问题,解决了,今天有小伙伴又聊到这个问题,就将这个问题复现出来,如果有人看到这个问题,可以帮助解决这个问题。

复现

通过 jmeter 复制问题,由于问题已经被解决,但是可以通过 jmeter 100%复现该问题。

复现流程:

  1. 通过 jmeter 发起 http 请求,并且不释放请求。
  2. 停止 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 请求超时时间,不让请求无限的等待下去,就可以避免这个问题。