Apache Artemis同group-id消息被多消费者接收问题排查
问题分析与解决方案
你遇到的这个问题——本地Spring Boot应用能接收几乎所有分组消息,而部署在Wildfly-11上的应用仅能收到少量分组里的极少消息,结合你提供的ActiveMQ Artemis 1.5.5的broker.xml配置,我梳理了几个高概率的原因和对应的排查、解决方法:
1. 消费者预取(Prefetch)配置失衡
ActiveMQ Artemis客户端默认会预取一批消息到本地缓存,要是本地应用先建立连接,很可能会把大部分消息预取走,导致Wildfly上的消费者只能分到少量消息。
- Spring Boot本地应用:在连接工厂里设置较小的
prefetchSize,强制broker更均匀地分发消息:@Bean public ActiveMQConnectionFactory connectionFactory() { ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://<你的broker IP>:61616"); factory.setPrefetchSize(10); // 可根据业务调整数值 return factory; } - Wildfly服务器应用:在Wildfly的
standalone.xml(或domain.xml)里找到对应的JMS连接工厂配置,添加prefetch-size属性:<connection-factory name="RemoteConnectionFactory" entries="java:/jms/RemoteConnectionFactory" connectors="netty-connector" prefetch-size="10"/>
2. 冗余集群配置引发的路由异常
从你的broker.xml来看,你配置了broadcast-groups、discovery-groups和cluster-connections,但你明确说两个应用连接的是同一个Artemis实例,并非集群环境。这种多余的集群配置可能干扰消息的正常分发逻辑:
建议直接移除这三个配置块,重启Artemis后再测试。单实例模式下不需要这些集群相关的配置,去掉后能避免不必要的负载均衡逻辑影响。
3. Wildfly端消费者的配置差异排查
Wildfly容器的JMS配置可能和本地Spring Boot有差异,导致消费行为异常:
- 确认Wildfly里的消费者监听的是同一个队列
AlarmsQueue,且没有设置消息选择器(Message Selector)——如果有选择器,会过滤掉不符合条件的消息。 - 查看Wildfly的
server.log日志,排查是否有JMS连接中断、消息确认失败之类的异常或警告,这些都可能导致broker停止向该消费者分发消息。
4. 老旧Artemis版本的已知bug
Artemis 1.5.5是2017年的老版本,存在不少已修复的消息分发相关bug:
- 优先建议升级到Artemis 2.x的稳定版本,新版本修复了很多负载均衡和路由的问题,大概率能解决你的现象。
- 如果暂时无法升级,可以针对
AlarmsQueue调整消息负载均衡策略,在broker.xml的address-settings里新增配置:
这个策略会在消费者请求消息时才分发,能避免消息集中流向某一个消费者。<address-setting match="jms.queue.AlarmsQueue"> <message-load-balancing>ON_DEMAND</message-load-balancing> </address-setting>
5. 消息确认机制一致性检查
确认两个消费者的消息确认模式是否一致:
- 如果本地应用用的是
AUTO_ACKNOWLEDGE,而Wildfly应用用的是CLIENT_ACKNOWLEDGE但没正确调用message.acknowledge(),broker会认为消息未被处理,就不会再给这个消费者发新消息。 - 检查Wildfly应用的消费代码,确保消息处理完成后正确执行确认操作。
内容的提问来源于stack exchange,提问作者OGI
相关产品推荐
相关产品推荐

