【问题标题】:Load Balancing Client Sessions负载平衡客户端会话
【发布时间】:2018-03-23 15:50:25
【问题描述】:

我有一个 2 台服务器 ActiveMQ Artemis 集群设置,使用 JGroups 进行发现工作正常。然后在我的应用程序中,ConnectionFactory 是通过 ActiveMQJMSClient 创建的:

final ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(
    "jgroups://test-cluster?file=jgroups-file-ping.xml&connectionLoadBalancingPolicyClassName=org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy", "test-cluster");

然后生产者和消费者由 Spring 处理。但是,当 Spring 在启动时创建 10 个消费者时,我看到所有 10 个消费者都转到同一个 Artemis 服务器。

这是 Spring JMS 配置:

@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);

    return factory;
}

然后在应用程序启动时,我在 JmsListenerConfigurer 中调用它:

public static void registerEndPoint(final JmsListenerEndpointRegistrar registrar,
    String endPointName, String dest, MessageListener listener) {
    final SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();

    endpoint.setId(endPointName);
    endpoint.setDestination(dest);
    endpoint.setMessageListener(listener);
    registrar.registerEndpoint(endpoint);
}

有没有办法进行设置,以便在每个 Artemis 服务器上有 5 个消费者?

【问题讨论】:

  • Spring 组件创建了多少个实际连接?如果它只创建一个连接,那就可以解释为什么所有客户端都在一个代理上。
  • 我只创建了一个 ConnectionFactory,但它随后使用该 ConnectionFactory 创建了 10 个消费者。
  • 顾名思义,“connectionLoadBalancingPolicyClassName”适用于连接,而不是消费者。如果您只创建一个连接,您将只连接到一个代理。在该连接上创建的所有消费者、生产者等都将位于相应的代理上。需要明确的是,Artemis 集群中的消息将被移动以防止消费者饥饿。
  • 这是有道理的。在那种情况下,问题在于spring只从连接工厂创建一个连接,有没有办法调整这个?我们看到,如果至少有一个应用程序连接到每个代理,则消息不会在 Artemis 集群中移动。这会导致大多数消息发送到单个 Artemis 代理,但只有一个应用程序连接到它,而其他应用程序连接到另一个代理不做任何处理。
  • 集群总是更喜欢本地消费者而不是远程消费者。如果没有本地消费者,它只会重新分发消息。但是,您可以通过为消息负载平衡 (activemq.apache.org/artemis/docs/latest/…) 指定 STRICT 来强制消息负载平衡。也就是说,如果您只有 2 个应用程序,那么我建议您实际上不需要集群。 Artemis 具有良好的性能,因此您可能只需一个经纪人即可实现您的性能目标。

标签: java jms spring-jms activemq-artemis


【解决方案1】:

Spring 的DefaultJmsListenerContainerFactory 有一个缓存级别,可以更改为CACHE_NONE,CACHE_CONNECTION,CACHE_SESSIONCACHE_AUTO

我必须将其设置为 CACHE_NONE,以便 Spring 在连接工厂中创建多个连接。

【讨论】:

    猜你喜欢
    • 2011-02-11
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多