ActiveMQ故障转移重连时主题无法传播问题咨询(跨WAN代理网络)
解决方案:ActiveMQ 5.14.0 故障转移重连后主题传播失效问题
根据你描述的多Broker A实例连接单Broker B的双向WAN桥接架构,以及故障转移重连后非持久化主题无法正常传播的问题,结合ActiveMQ 5.14.0的特性、Java 8环境和RHEL 6的部署场景,我整理了以下针对性的排查和修复方案:
先聊聊可能的根因
这种故障通常和几个关键点相关:
- 网络桥接在重连后没有正确同步远程Broker的主题路由信息
- 启用的通知消息(Advisory)订阅状态未在重连后恢复
- 非持久化主题的临时订阅状态在故障转移时丢失
- ActiveMQ 5.14.0本身存在的网络桥接相关已知Bug
分步解决办法
1. 检查并优化网络连接器配置
首先确保Broker A到Broker B的网络连接器配置覆盖了双向桥接的关键参数,避免重连后路由逻辑失效。修改Broker A的activemq.xml中的网络连接器配置:
<networkConnector name="brokerA-to-brokerB" uri="static:(tcp://brokerB-host:61616)" duplex="true" dynamicOnly="true" networkTTL="3" prefetchSize="1" decreaseNetworkConsumerPriority="true"> <dynamicallyIncludedDestinations> <topic physicalName=">"/> <!-- 确保通知主题也被桥接 --> <topic physicalName="ActiveMQ.Advisory>"/> </dynamicallyIncludedDestinations> </networkConnector>
这里划几个重点:
duplex="true":双向桥接必须开,否则消息没法在Broker A和B之间双向流转dynamicOnly="true":只路由有订阅者的主题,减少无效路由的同时,确保重连后能自动发现新的订阅- 明确包含所有主题(
>通配符)和通知主题:避免漏掉关键的路由同步信号
2. 强制主题订阅状态刷新
故障转移后,Broker可能不会主动刷新远程主题的订阅信息,我们可以通过配置让它自动处理,或者手动触发:
自动刷新配置
在Broker的destinationPolicy中添加以下配置,让主题在有新订阅(包括重连后的远程订阅)时自动重新路由:
<broker xmlns="http://activemq.apache.org/schema/core" ...> <destinationPolicy> <policyMap> <policyEntries> <policyEntry topic=">" > <networkBridgeFilterFactory> <conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/> </networkBridgeFilterFactory> <!-- 非持久化主题重连后补发最新消息 --> <alwaysRetroactive>true</alwaysRetroactive> </policyEntry> </policyEntries> </policyMap> </destinationPolicy> </broker>
replayWhenNoConsumers="true"会在消费者重新连接时触发主题消息的重新分发,alwaysRetroactive="true"则确保新订阅者(包括重连后的远程Broker)能拿到当前内存中的最新消息。
手动触发(应急用)
如果配置修改后需要立即验证,可以通过JMX连接到Broker A,找到对应的NetworkConnector实例,执行refreshDestinations()方法,强制同步远程Broker的主题状态。
3. 规避ActiveMQ 5.14.0的已知Bug
ActiveMQ 5.14.0存在几个和网络桥接、故障转移相关的Bug,比如非持久化主题重连后远程订阅收不到消息、双向桥接路由状态不同步等问题。虽然暂时没法升级版本,但可以通过以下配置规避:
- 确保Broker的
persistent="false"(你已经用非持久化主题,这个应该已经满足) - 关闭不必要的持久化相关配置,比如
useDatabase="false",避免持久化层干扰临时订阅状态 - 为每个Broker A的网络连接器添加
reconnectDelay="5000"参数,避免过于频繁的重连导致路由状态混乱
4. 验证故障转移流程
最后建议模拟故障场景验证修复效果:
- 先停止Broker B,等待Broker A的日志显示网络连接器断开
- 重启Broker B,观察Broker A的日志,确认出现
NetworkConnector connected to tcp://brokerB-host:61616的日志 - 在某个Broker A的订阅者发送一条测试消息,检查其他Broker A的订阅者是否能正常接收
- 查看Broker的日志,确认没有
Destination not found或Route not established之类的错误
内容的提问来源于stack exchange,提问作者Blake M.




