You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ActiveMQ Artemis集群Spring消费者全部集中单节点问题求助

解决ActiveMQ Artemis集群中Spring JMS消费者负载均衡失效问题

我来帮你分析这个负载均衡不生效的问题,核心原因和解决方法如下:

问题根源

你配置的RoundRobinConnectionLoadBalancingPolicy是针对新连接创建时的节点选择策略,但Spring的DefaultJmsListenerContainerFactory默认会复用同一个连接(通过内置的连接缓存机制),所有10个消费者都共享这一个连接。既然连接只创建了一次,自然所有消费者都只会连接到同一台Artemis服务器,负载均衡策略没有触发的机会。

具体解决方法

1. 禁用连接缓存,让每个消费者使用独立连接

修改你的DefaultJmsListenerContainerFactory配置,添加setCacheLevel(CACHE_NONE),这样每个消费者实例都会创建自己独立的连接,每次创建连接时Artemis的轮询负载均衡策略就会生效:

@Bean 
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() throws Exception { 
    final ConnectionFactory cf = getActiveMQConnectionFactory(); 
    final DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); 
    factory.setConnectionFactory(cf); 
    factory.setConcurrency("10-20"); 
    factory.setSessionTransacted(true); 
    factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
    // 禁用连接/会话缓存,强制每个消费者创建独立连接
    factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_NONE);
    return factory; 
}

2. 使用池化连接工厂并配置合理的池参数

如果希望复用连接同时实现负载均衡,可以使用Artemis自带的池化连接工厂,确保连接池中有足够多的连接,并且每个消费者能获取到不同的连接:

@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
    ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(
        "jgroups://test-cluster?file=jgroups-file-ping.xml&connectionLoadBalancingPolicyClassName=org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy", 
        "test-cluster"
    );
    // 开启池化并配置参数
    cf.setPooled(true);
    cf.setMaxPoolSize(20); // 最大连接数要大于等于并发消费者数
    cf.setMinPoolSize(10); // 初始连接数匹配初始并发数
    return cf;
}

然后在容器工厂中使用这个池化连接工厂,同时设置合适的缓存级别(比如CACHE_SESSION),这样每个会话会从池中获取不同的连接,间接实现负载均衡。

3. 验证集群发现和负载均衡策略是否正常工作

  • 检查JGroups配置文件jgroups-file-ping.xml是否正确,确保两个Artemis节点能互相发现(可以通过Artemis控制台查看集群节点列表,确认两个节点都在线)。
  • 添加Artemis客户端调试日志,查看连接创建时的节点选择情况:
    <!-- 在logback或log4j配置中添加 -->
    <logger name="org.apache.activemq.artemis.core.client" level="DEBUG"/>
    
    如果日志显示每次创建连接都选择同一个节点,说明负载均衡策略没有正确初始化,或者集群发现只返回了一个节点,需要排查JGroups集群的连通性。

额外提示

当你设置concurrency="10-20"时,Spring会初始创建10个消费者实例。只要每个实例使用独立的连接(或从连接池获取不同的连接),Artemis的轮询策略就会把这些消费者均匀分配到两个集群节点上。

内容的提问来源于stack exchange,提问作者Samyel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:55:32