【问题标题】:Cancel ActiveMQ message取消 ActiveMQ 消息
【发布时间】:2018-02-03 06:11:31
【问题描述】:

我不确定 ActiveMQ 是否是一个合适的工具...

我有一个任务队列和多个消费者,所以我的想法是使用 ActiveMQ 发布任务,然后由消费者消费。

但我需要能够取消任务,如果它还没有处理...

是否有用于从 ActiveMQ 中的队列中删除消息的 API?

Destination destination = session.createQueue(TOPIC_NAME);
MessageProducer producer = session.createProducer(destination);
ObjectMessage message = session.createObjectMessage(jobData);
producer.send(message);
...
producer.cancel(message); (?)

用例是,出于任何原因,不再需要执行该任务,并且该任务是资源消耗。

【问题讨论】:

标签: java activemq


【解决方案1】:

ActiveMQ 公开了一个允许此类操作的 JMX 接口。为队列建模的 MBean(例如 org.apache.activemq:type=broker,brokerName=amq,destinationType=Queue,destinationName=my_queue)公开了一个方法 removeMessage(字符串 id)。还有一些方法可以删除与特定模式匹配的消息。

据我所知,这个功能没有暴露在 JMX 之外。

但是……

我有一种讨厌的感觉,即对特定消息起作用的 JMX 操作只对分页到内存中的消息起作用。默认情况下,这通常是最接近队列头部的 400 条消息。我知道这对于选择器操作是正确的,尽管我不确定 JMX。

一些 ActiveMQ 消息存储(例如 JDBC 存储)也可能提供一种获取底层消息数据并对其进行操作的方法。在关系数据库上,这通常是安全的,因为在 JMS 操作中“正在运行”的消息将在数据库级别锁定。但是,对于本应简单的工作来说,这会带来很多麻烦。

我想知道 JMS 是否真的适合这项工作?它并不是真正用于随机访问。也许某种分布式数据缓存会更好(jgroups,Hazelcast,...)?

【讨论】:

    【解决方案2】:

    如何设置消息的过期时间? http://activemq.apache.org/how-do-i-set-the-message-expiration.html

    如果您希望在特定时间范围内未处理/消费的消息被删除,那么消息过期对我来说似乎是答案。

    【讨论】:

      【解决方案3】:

      对于那些正在寻找直接答案的人,有一个 JMS API 可以控制这种行为:

      JMS API docs:

      setTimeToLive(long timeToLive)

      指定使用此JMSProducer 发送的消息的生存时间。

      所以你可以在发送之前在生产者上设置这个值:

      ...
      producer.setTimeToLive(30000L);
      producer.send();
      

      使用此特定设置,消息将在被 Message Broker 删除之前保留 30 秒

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-06
        • 2012-12-06
        • 1970-01-01
        • 2015-11-25
        • 2021-04-02
        • 2020-01-17
        • 2012-04-28
        • 2013-01-24
        相关资源
        最近更新 更多