ActiveMQ使用问题整理

producer的复用

一开始研究ActiveMQ的资料时,官网只说了connection和session最好复用,在我认识里,producer和consumer是由session创建出来的,session复用没问题,producer应该资源占用没那么大吧?

所以在一开始对项目组暴露的封装好的api接口中,client每发送一条消息,都会自动创建一个producer,随着发送消息的越来越多,在mq控制台上看到的生产者数量就越来越多,mq内存占用越来越大,从而导致mq的宕机。

最后的解决方法是在程序里复用producer,由于client需要持续往三个队列发送消息,因此使用了hashmap来存放建好的producer,map里键是目的地,值则是MessageProducer对象。

每次发送消息时,需要检查是否producer可用,主要是检查会话是否正常。

failover机制的问题

在项目上线后,需求方要求Agent可以在故障时自动切换到另一个MQ集群以实现容错,且在原集群正常后可以自动切换回来。

这个需求直觉上就是ActiveMQ的failover机制,只需要在建立连接时把randomize设置为false,然后加个priorityBackup=true,failover中配置上两个MQ集群的F5就OK,实际上我们也是这么做的。

上线后才发现了一个问题,只要有一点网络抖动,或者因为inactivityMonitor导致的连接断开,那么Agent就会自动连接到另一个集群,而后再尝试连接回来。也就是说,不会尝试多次第一个地址,而是直接尝试第二个可用的地址,就算将配置写成

ip1,ip1,ip2

的形式也不行。因为源码中在识别uri添加uri到重连列表时有一个去重的机制,在FailoverTransport中:

public void add(boolean rebalance, URI u[]) {

     boolean newURI = false;

     for (URI uri : u) {

           if (!contains(uri)) {

                  uris.add(uri);

                   newURI = true;

           }

     }

     if (newURI) {  

      reconnect(rebalance);

     }

}

由于我们使用的是MQ上自带的系统消息来判断Agent是否在线,这样就会出现两个集群的ActiveMQ都会上送一条agent连接到该集群的提示,如果离线消息处理不及时,上层就会出现一个agent连接两个mq的情况。

实际解决方法还没有想到,目前想到的就是先把InactivityMonitor给关了,再看看效果吧

Channel was inactive for too long

这个问题出现在使用了上述的failover机制后,由于InactivityMonitor机制,一般情况下如果没有数据包,那么MQ和Agent会互相发送keepAlive Info数据包,是不会出现问题的。但是在MQ负载较高的情况下,会出现无法发送KeepAlive Info的问题(推测),因此InactivityMonitor就会断开连接,而后自动重连到另一个集群再连接回来。

在这种情况下,考虑两种方案

1.彻底关闭该功能

2.延长检测时间,比如10分钟内没数据交互才关闭。

目前暂定方案2具体测试情况待上线后检验

无限重连导致连接暴增

在测试环境上发现一个场景,agent不停发起对mq的重连,但是连接未被关闭,一段时间后,火墙就被这些连接占满了。

现在初步判断原因是mq被连接撑爆,导致mq不停关闭连接,agent又不停尝试重连,具体需要再进行测试。

这个问题的解决方法有两种

1.增加mq集群数量,限制每台mq的连接数

2.放弃failover机制,而是改用自己写的逻辑来进行重连。

具体解决方法待确定,后续更新

KahaDB无法及时清理db-*.log

问题原因已经找到,是ActiveMQ的一个bug:

ActiveMQ使用KahaDB进行消息的持久化存储,在KahaDB的db-.log文件中,存放的是消息和消息被消费者接收的ack数据(messages and acknowledgement),只有一个db-.log文件中所有的消息都被消费(都存在ack)后,这个db-*.log才会被清理。

那么现在存在一种情况,如果MQ上堆积了一条消息,许久没被消费。那么这条消息所在的db-1.log就不会被清理,也就是说db-1.log中所有其他已经被消费的消息也都不会被清理。如果db-2.log,db-3.log中存在db-1.log中的已经被消费的消息的ack数据,这个ack数据也是不能被清理的。原因是如果清理了ack数据,那么在MQ宕机重启后,db-1.log中的被消费的消息又会被置为未消费。因此就会产生一个连锁反应,只要有一条消息卡在MQ上,就可能后续的数据文件均无法被删除。当然连锁反应也有可能在某个环节被打破,比如某个文件刚好包含了自己所有消息的ack和上一个文件的消息的ack数据,但是如果一直连锁下去,文件系统的确是会被撑爆。

在测试环境已重现这个问题

这个bug在ActiveMQ-5.14.0版本中被解决,解决方法是把第一个数据文件中消息的ack给迁移到某个数据文件中。我也在测试环境搭了5.14.1版本的ActiveMQ进行了测试。

可惜我们用的版本是ActiveMQ-5.11.1……………………

解决方法是:

1、尽量减少MQ上的消息堆积的情况,比如设置消息的超时时间,定时清理等。如果堆积了要及时处理,不能让MQ上长期堆积相同的消息。

2、减小db-*.log的文件大小,理论上可以使脏数据的影响范围降低

3、设置KahaDB多实例,让队列之间的数据文件互不干扰。
设置方法


亲测,在分别对两个队列设置KahaDB多实例后,生产者生产持久化消息的TPS提升了

4、升级MQ

MQ服务器上出现大量CLOSE_WAIT连接

CLOSE_WAIT表示一个连接被被动关闭了,服务器没有检测到,因此程序忽略了继续进行连接的关闭。最麻烦的是CLOSE_WAIT的连接会占用amq的总连接数,因此如果要清理,只能重启mq来解决。
有一篇文章对TIME_WAIT和CLOSE_WAIT解释得很详细。
http://www.cnblogs.com/sunxucool/p/3449068.html
出现这个问题后,可能直接导致activemq报出timer already cancelled,连接超限,无法建立线程OOM等报错。(推测)
该问题在JIRA上已经被关闭,见AMQ-5543和AMQ-5251。

经过一段时间的研究,发现是我的代码触发了MQ 的一个bug代码中建立了过多的JMX连接,导致服务器无法建立新的线程,从而导致连接无法被正常处理,而后连接被客户端关闭,就出现了close_wait。

这个bug连接的是InactivityMonitor中建立ReadChecker和WriteCheck的bug,出现问题时会导致MQ上报出大量的Timer Already Cancelled报错,因为无法建立新的checker线程了,但是代码中仍然进行了checker的Timer类的配置,所以抛出了timer already cancelled的异常。在AMQ 5.13及以后的版本已修复该问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 1、前言 之前我们通过两篇文章(架构设计:系统间通信(19)——MQ:消息协议(上)、架构设计:系统间通信(20)...
    境里婆娑阅读 1,871评论 0 4
  • kafka的定义:是一个分布式消息系统,由LinkedIn使用Scala编写,用作LinkedIn的活动流(Act...
    时待吾阅读 5,311评论 1 15
  • ActiveMQ 即时通讯服务 浅析http://www.cnblogs.com/hoojo/p/active_m...
    bboymonk阅读 1,481评论 0 11
  • 好久没写爬出了,这段时间都这折腾别的,今天看了个视频爬图片,自己无聊也写了个千图网的爬虫,结果写了好久,真是生疏,...
    蜗牛仔阅读 1,994评论 1 9