使用 Spring Boot 对 Artemis Cluster 进行持久订阅

Posted

技术标签:

【中文标题】使用 Spring Boot 对 Artemis Cluster 进行持久订阅【英文标题】:Durable subscription for Artemis Cluster with Springboot 【发布时间】:2018-05-25 09:41:05 【问题描述】:

我已经创建了 2 个节点的 Artemis 集群并成功连接到我的 Spring-boot 应用程序 (github link),实现基于 clustered-static-discovery

现在我正在用它测试持久订阅有一些奇怪的行为 我正在生产 5 个味精,只消耗 3 个

   @Bean
    public MessageListenerContainer listenerContainer1(@Qualifier("connectionFactory") ConnectionFactory connectionFactory, Consumer consumer, SimpleMessageConverter messageConverter, @Qualifier("topic") Topic topic) 
        DefaultMessageListenerContainer defaultMessageListenerContainer =
                new DefaultMessageListenerContainer();


    @Bean("connectionFactory")
    public ConnectionFactory activeMQJMSConnectionFactory(@Qualifier("amqTransportConfiguration") TransportConfiguration transportConfiguration) throws JMSException 
        ActiveMQJMSConnectionFactory activeMQJMSConnectionFactory =
                new ActiveMQJMSConnectionFactory( false, transportConfiguration);
        activeMQJMSConnectionFactory.setPassword("admin");
        activeMQJMSConnectionFactory.setUser("admin");
        activeMQJMSConnectionFactory.setClientID("admin");
        return activeMQJMSConnectionFactory;
    
defaultMessageListenerContainer.setConnectionFactory(connectionFactory);
    defaultMessageListenerContainer.setDestination(topic);
    defaultMessageListenerContainer.setMessageListener(consumer);
    defaultMessageListenerContainer.setSessionAcknowledgeMode(1);
    defaultMessageListenerContainer.setSubscriptionName("mySub");
    defaultMessageListenerContainer.setSubscriptionDurable(true);
    defaultMessageListenerContainer.setMessageConverter(messageConverter);
    return defaultMessageListenerContainer;

这里是完整的config

我已经通过http://localhost:816i/hawtio/ wrb UI for artemis 发现生产者只收到 5 条消息中的 5 条

(消息负载平衡 -> 严格)

我在这里做错了什么?

【问题讨论】:

我有一个具有 STRICT 消息负载平衡的两个代理集群(来自 clustered-static-discovery 示例),您的测试运行良好。我还取消了那些使订阅持久的部分的注释,这也成功了。编辑您的问题并向我们提供 broker.xml。 嗨 @ArtursLicis 感谢您的回复,这里是第一台服务器 broker.xml:github.com/techguy-bhushan/ApacheArtemisCluster/tree/master/… 第二台服务器代理 xml ->github.com/techguy-bhushan/ApacheArtemisCluster/tree/master/… 另外,我取消了订阅者行的注释,还从 connectionFactory 中删除了客户端 ID,请提取克隆代码并重新运行测试,您能否分享您的集群代理 XML。我不确定我在代理端或弹簧配置上做错了什么。 您肯定签入了错误的配置或无法正常工作的代码。在您的应用程序中,您尝试连接到端口 9616,该端口从未在配置中定义——因此启动失败。当我更改此 61616(第一台服务器)时,它因安全异常而失败(要解决此问题,您可以关闭安全性或配置它的属性)。看起来您只需要仔细检查所有配置和设置。 对不起,我已经用 9616 端口测试过,我忘记在推送之前更改它,如果你用 61617 替换它仍然无法正常工作 【参考方案1】:

问题出在 Artemis 依赖项中,现有使用的依赖项不知何故无法处理与集群的 PubSab 连接,我没有找到丢失消息的任何错误日志。 我改变了依赖

<dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>artemis-jms-client-all</artifactId>
        <version>2.2.0</version>
    </dependency>

现在它正在工作。

【讨论】:

【参考方案2】:

看起来问题出在代码上。两个不同的持久订阅共享相同的持久订阅名称。在为每个 MessageListenerContainer 实例使用唯一订阅名称后,我能够通过您的测试:

//listener container (1)
defaultMessageListenerContainer.setDurableSubscriptionName("sub1");

/* --- */

//listener container (2)
defaultMessageListenerContainer.setDurableSubscriptionName("sub2");

【讨论】:

如果您将从 Web UI 中看到所有消息都将发送到一个节点,而不是两个节点之间的负载平衡(循环方式).. 能否请您分享您的集群配置 如果你将运行github.com/jbertram/activemq-artemis/blob/…(请在运行前删除connection3和connection4)然后你会看到两个节点之间的负载平衡 该示例在获取连接方面做了一个技巧:首先,创建了未使用的 initialConnection,只有在 2 秒延迟后,才会创建其余连接,这些连接在所有服务器之间进行负载平衡。注意该代码中的注释:grab an initial connection and wait, in reality you wouldn't do it this way but since we want to ensure an equal load balance we do this and then create 4 connections round robined. 我已经创建了初始连接,但问题是 samw 谢谢,这是一次宝贵的经验。令人惊讶的是,我最近遇到了类似的情况:在将代理从 ActiveMQ 切换到 Artemis 后,我正在测试转移。我找不到包含原始目的地名称的预期标题;原因是错误的 JMS 客户端库。

以上是关于使用 Spring Boot 对 Artemis Cluster 进行持久订阅的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Stomp over WS 与嵌入式 Artemis 代理“目标不存在”

如何使用嵌入式 ActiveMQ Artemis 为 Spring Boot 配置 max-delivery-attempts?

ActiveMQ Artemis 前缀为“jms.topic”。到 Spring Boot Client 上定义的所有主题名称

Spring Boot学习笔记——Spring Boot与ActiveMQ的集成

使用 Spring Integration 向 ActiveMQ Artemis 主题发送消息

使用spring-boot对rest服务进行访问控制