ActiveMQ连接不释放问题

ActiveMQ连接不释放问题

实际问题为:大量失效连接处于ESTABLISHED状态.

检查问题的过程

线上出现了activemq连接不上的报错The JMS Connection has failed

到mq所在的服务查看,连接数已经占满了,使用命令

netstat -antp | grep 61615| grep ESTABLISHED| wc -l

获取tcp端口为61615的ESTABLISHED连接数量,其值已经与activeMQ中配置的maximumConnections=3000一致,所以无法建立新的连接.

查看一下有一台服务器的连接数有2400个,假设这个服务器的ip为a好了,到这台服务器上查看连接数,却发现其与mq的连接仅有2个.

也就是说当前的问题是

源端已经检查到tcp连接的断开,而目的端却未发现连接已经断开

遇事不决,谷歌一下

你遇到的问题,大部分情况下总是有人已经遇到过了的.

如果没有的话,恭喜你.

按照这个问题,去网上搜索activeMQ是否存在类似的问题,许久无果.

不过这个文档有一些帮助

https://www.jianshu.com/p/a1c3aba4af96

可以查看连接建立的时间.

是否是真实存在的ip?

由于a的服务器ip并非物理ip,即设备上没有这个ip的网卡,怀疑有其他的设备也使用了这个ip来连接mq,因此使用tcpdump监听了一段时间,并没有发现有那些虚假连接的包传输.

使用的命令如下

tcpdump -i eth0 port 61615 and src host a
#其中eth0是使用的网卡,可以通过ip来确认,ip a/ifconfig可以查看网卡的ip.

服务器配置问题?

此时怀疑服务器是否存在什么配置导致其无法检查到tcp连接的断开,于是使用nc -lk监听了一个新的端口,然后使用服务器a来telnet这个端口,然而关闭telnet后,服务器确实能够检查到连接的断开.

强制断开的连接不会被检测到断开?

实际上这个猜想是正确的,但实验手段存在问题.

我使用的实验方式如下

  1. telnet a 61615 &
  2. kill -9 pid
  3. 检查连接状态,仍然是time-wait

linux下,进程销毁后,其相关的资源将会被全部释放

然而在排查问题的当时,并未想到这个关键点,也由此导致了后面的弯路.

MQ的问题?

现网的mq版本和本地的mq版本是一致的,所以可以使用本地的mq来进行测试.

检查了创建连接的代码后发现仅关闭了connection而未关闭session,因此编写了一个简单的连接product来进行测试,然而并不存在这种问题.

检查了现网和本地的mq配置后,发现现网的配置多了一条wireFormat.maxInactivityDuration=0

搜索了一下这个参数,找到了下面这篇文章

https://blog.csdn.net/tcdpyh6sa3/article/details/60960434

由此猜测是由该配置引发的问题.

于是在本地进行相应的测试,然而在调用connection.close后,服务端仍然能够发现连接已经关闭.

恢复

由于现网情况,无法随意重启,并且部分业务仍然在正常运行,只有一个新上线的业务无法连接到mq,因此申请了上线后去除了该参数,并重启了mq.

观察了两天,没有再次出现这种情况.

实际问题

在上线的时候,记忆恢复了

  1. 一年半前测试过mq在高丢包率下的工作情况,当时设置了40%的丢包率之后,mq也出现了连接未能检测到关闭的情况.
  2. 应用在连接时,直接断开网络,随后关闭应用,再次连接网络,对端无法检测到连接已经关闭,若设置了keepalive则可以在一段时间后检查到连接已经关闭.

也就是所谓的半连接问题,tcp/ip中有专门一章是讲解这个问题的.

知道了问题,反推问题的出现过程就很简单了,设置wireFormat.maxInactivityDuration=0参数后,连接mq,并且在断开之前断开网络,随后恢复网络,便能够复现这种问题.

这个参数默认是30000,即30秒,也就是设置keep-alive为30秒,能够检测到连接失效的情况.

为何没有第一时间想到问题根因

  1. 未进行相关问题的记录,印象不深.
  2. 对tcp/ip还不够熟悉.
  3. 理论情况遇到的不多.
  4. 实验问题的手段需要仔细考虑.
  5. 线上服务器一般不会修改配置,未第一时间检查配置.
发布了27 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/l1161558158/article/details/103461934