当前位置: 首页 > 知识库问答 >
问题:

如何设置ActiveMQ Artemis重新交付策略以避免阻塞队列

夏振国
2023-03-14

问题

在我看来不一致的是,如果您连续发布消息,Artemis似乎保留了顺序,而如果消息之间有轻微的延迟,那么队列不会阻塞,只有失败的消息被延迟调度(根据文档)。

我试图找到一个解决方案,这样如果一个消息失败,并需要在10分钟内重新传递,它不会阻止后续的消息。

@SpringBootApplication
public class ArtemisTestApplication
{

    private Logger logger = LoggerFactory.getLogger(ArtemisTestApplication.class);

    @Autowired
    private JmsTemplate jmsTemplate;

    @PostConstruct
    public void init()
    {
        send("Message1");
        send("Message2");
        send("Message3");
        send("Message4");
        send("Message5");
    }

    public void send(String msg)
    {
        logger.debug("Sending message :{}", msg);
        jmsTemplate.convertAndSend("jms.queue.TestQueue", msg);
    }

    public static void main(String[] args)
    {
        SpringApplication.run(ArtemisTestApplication.class, args);
    }

}
@Component
public class TestConsumer
{
    private Logger logger = LoggerFactory.getLogger(TestConsumer.class);

    @JmsListener(destination = "jms.queue.TestQueue")
    public void receive(TextMessage message) throws JMSException
    {
        logger.debug("Message received: {}", message.getText());
        throw new RuntimeException("Force redelivery policy");
    }
}
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-artemis</artifactId>
    </dependency>
spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=
spring.artemis.password=
<address-settings>      
    <address-setting match="jms.queue.TestQueue">            
        <dead-letter-address>DLQ</dead-letter-address>                      
        <redelivery-delay>0</redelivery-delay>    
        <max-delivery-attempts>3</max-delivery-attempts>
    </address-setting>    
  </address-settings>

<addresses>     
    <address name="DLQ">            
        <anycast>               
          <queue name="DLQ" />            
        </anycast>         
      </address>       
      <address name="jms.queue.TestQueue">            
        <anycast>               
          <queue name="jms.queue.TestQueue" />            
        </anycast>         
      </address>                      
</addresses>

共有1个答案

卓麒
2023-03-14

我已经得出结论,这是一个与阿尔特弥斯的bug。我为此提出了一张罚单,并留下了一条评论,其他人也遇到了同样的问题。

https://issues.apache.org/jira/browse/artemis-2417

与此同时,我不得不更改我们的客户端应用程序来处理重新交付策略本身。如果读取消息时出现错误,则在消息上增加一个计数器,并以所需的延迟将其作为新消息写入。然后确认正在使用的消息以解除阻塞队列并允许读取其他消息。我保留了在代理上配置的重新交付策略,以备出现此逻辑之外的错误或未捕获的错误时使用。这并不理想,但至少现在符合要求。

 类似资料:
  • 我正在使用: SpringBoot 2.0.4 ActiveMQ 5.15.5 Apache Camel 2.22.0 Java1.8 太棒了 马文 基本上,我有一个带有Apache Camel路由的SpringBoot应用程序,它使用来自ActiveMQ的消息和事务。我需要在ActiveMQ上设置一个Re的策略,所以当处理中发生错误时,消息会被重试多次。 我已经用bean为ActiveMQ创建了

  • 我正在使用ActiveMQ Artemis 2.17和Spring Boot 2.5.7。我正在发布关于主题和队列的消息并使用它。所有这些都是通过JMS完成的。所有队列(选播或多播)都是耐用的。我的主题(多播地址)有两个持久队列,以便有两个独立的使用者。在我的主题中,这两个消费者使用持久和共享订阅(JMS 2.0)。所有处理都是事务性的,通过Atomikos事务管理器进行管理(我需要它来提交数据库

  • 问题内容: 考虑以下代码: 我了解在上面的代码中,如果拥有同步块的所有权,并且同时如果线程尝试获取同步块,则需要内核等待。我想避免这种情况,并在块之前旋转,直到调用等待并离开该块的所有权为止。那可能吗? 问题答案: JVM无需将进入锁定的同步块的步骤实现为硬块和上下文切换。它可以选择使用重量更轻的方法,例如旋转锁。实际上,Oracle JVM竭尽所能避免阻塞。因此,您可能会发现JVM已经为您完成了

  • 我有一个JMS队列,在那里我可以获得几种类型的消息。所有消息都是对象消息。我让Spring DMLC处理它们,并尝试将它们传递到外部endpoint。 每种消息类型都与不同的endpoint相关联。 如果消息必须传递到1个或多个endpoint,我认为阻塞使用者对我没有帮助。 我找不到任何非阻塞消费者的信息,我想知道它是否真的帮助我解决我的问题。

  • 谁能解释一下ActiveMQ重新交付策略实际上是如何工作的?它是在客户端还是在服务器端工作? 假设我有一个重新传递策略,每次尝试之间间隔30分钟,重新传递消息长达10分钟,那么失败的消息到底在哪里? 假设消息现在失败了,30分钟后重新发送,那么消息在哪里? http://activemq.apache.org/redelivery-policy.html http://activemq.apach

  • 问题内容: 我发现我的某些活动在启动时被阻止。因此,我在一个新项目中编写了该代码: 结果是第一次创建AdView对象会阻塞UI线程1到2秒钟。 有什么办法可以避免这种情况? 谢谢 问题答案: 您正在UI线程中创建AdView,这就是被阻止的原因。在AdView初始化期间,线程不会执行其他任何操作。 您可以尝试在另一个线程中加载AdView,也可以使用AsyncTask以用户界面安全的方式加载它。