【问题标题】:How to put a message back in the queue using latest SpringBoot and ActiveMQ classic如何使用最新的 SpringBoot 和 ActiveMQ 经典将消息放回队列
【发布时间】:2019-11-12 09:48:49
【问题描述】:

我正在设计一个简单的系统,其流程将是这样的:

Message Producer Microservice --> Active MQ --> Message Consumer Microservice --> Mongo DB

我需要设计一种排队策略,以便在 MongoDB 宕机时,我不应该丢失消息(因为消息使用者会将消息出列)。

我的消费者是这样写的:

    @JmsListener(destination = "Consumer.myconsumer.VirtualTopic.Tracking")
    public void onReceiveFromQueueConsumer2(TrackingRequest trackingRequest) {
        log.debug("Received tracking request from the queue by consumer 2");
        log.debug(trackingRequest.toString());
    }

您如何提供客户确认?

【问题讨论】:

  • @JustinBertram 我已经更新了这个问题以更清楚地说明问题。问题是,如果 MongoDB 宕机,我们如何在可能几个小时后处理相同的消息?

标签: spring-boot error-handling activemq


【解决方案1】:

您可以在“消息消费者微服务”中使用客户端确认模式。由于您使用的是 Spring JmsListener,因此您可以使用 containerFactory 定义侦听器容器,然后您可以使用 sessionAcknowledgeMode 在侦听器容器上设置所需的模式。请参阅the Spring documentation,了解更多关于您可能想在此处使用的确认模式的详细信息。

从 ActiveMQ 客户端的角度来看,您可以根据需要配置重新传递语义,以防发生故障。有关详细信息,请参阅ActiveMQ documentation

【讨论】:

  • 嗨,我已经编辑了这个问题,以了解如果我的消费者是使用 @JMSListener 编写的,如何获得客户的确认。谢谢。
  • 我更新了我的答案以解决您问题中的变化。希望有帮助!
【解决方案2】:

好的,所以我能够解决这个难题,这就是您的配置应该是什么样的(感谢贾斯汀的宝贵意见):

    @Bean
    public ActiveMQConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(brokerUrl);
        connectionFactory.setPassword(userName);
        connectionFactory.setUserName(password);
        connectionFactory.setTrustAllPackages(true);
        connectionFactory.setRedeliveryPolicy(redeliveryPolicy());
        return connectionFactory;
    }
    @Bean
    public JmsTemplate jmsTemplate() {
        JmsTemplate template = new JmsTemplate();
        template.setConnectionFactory(connectionFactory());
        return template;
    }
    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
        DefaultJmsListenerContainerFactory listenerCF = new DefaultJmsListenerContainerFactory();
        listenerCF.setConnectionFactory(connectionFactory());
        listenerCF.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
        listenerCF.setSessionTransacted(true);
        return listenerCF;
    }
    @Bean
    public RedeliveryPolicy redeliveryPolicy() {
        RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
        redeliveryPolicy.setRedeliveryDelay(600000L); //keep trying every 10 minutes
        redeliveryPolicy.setMaximumRedeliveries(-1); //Keep trying till its successfully inserted
        return redeliveryPolicy;
    }

【讨论】:

  • 我的回答是否解决了您的问题?如果是这样,请将其标记为这样,以帮助将来可能有同样问题的其他人。谢谢!
猜你喜欢
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 2019-02-08
  • 2017-09-13
  • 1970-01-01
  • 2021-09-10
相关资源
最近更新 更多