避免在JMS / ActiveMQ上重复的消息

有一种方法可以抑制ActiveMQ服务器上定义的队列上的重复消息吗?

我尝试手动定义JMSMessageID(message.setJMSMessageID(“uniqueid”)),但服务器忽略此修改并传递带有内置生成的JMSMessageID的消息。

根据规范,我没有找到关于如何重复删除邮件的参考。

在HornetQ中,为了解决这个问题,我们需要在消息定义中声明HQ特定属性org.hornetq.core.message.impl.HDR_DUPLICATE_DETECTION_ID。

即:

Message jmsMessage = session.createMessage(); String myUniqueID = "This is my unique id"; // Could use a UUID for this message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID); 

有人知道ActiveMQ是否有类似的解决方案?

您应该查看Apache Camel,它提供了一个可与任何JMS提供程序一起使用的Idempotent使用者组件,请参阅: http : //camel.apache.org/idempotent-consumer.html

将它与ActiveMQ组件结合使用可以非常简单地使用JMS,请参阅: http : //camel.apache.org/activemq.html

我怀疑ActiveMQ是否原生支持它,但实现幂等消费者应该很容易。 一种方法是在生产者端为每条消息添加一个唯一的标识符,现在在消费者端使用存储(db,cache等),可以检查消息是否已经在之前和之前接收过。继续根据该检查进行处理。

我看到以前的stackoverflow问题沿着相同的路线–Apache ActiveMQ 5.3 – 如何配置队列以拒绝重复的消息? ,这也可能有所帮助。

现在支持删除烘焙到ActiveMQ传输中的重复消息。 请参阅“ 连接配置指南”中的配置值auditDepthauditMaximumProducerNumber

有一种方法可以让ActiveMQ根据JMS属性过滤重复项。 它涉及编写Activemq 插件 。 将重复消息发送到deadletter队列的基本代理filter就是这样的

 import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.activemq.broker.Broker; import org.apache.activemq.command.Message; import org.apache.activemq.command.ActiveMQMessage; import org.apache.activemq.broker.BrokerFilter; import org.apache.activemq.broker.ConnectionContext; import org.apache.activemq.command.ConnectionInfo; import org.apache.activemq.broker.ProducerBrokerExchange; public class DuplicateFilterBroker extends BrokerFilter { String messagePropertyName; boolean switchValue; public DuplicateFilterBroker(Broker next, String messagePropertyName) { super(next); this.messagePropertyName = messagePropertyName; } public boolean hasDuplicate(String propertyValue){ switchValue = propertyValue; return switchValue; } public void send(ProducerBrokerExchange producerExchange, Message msg) throws Exception { ActiveMQMessage amqmsg = (ActiveMQMessage)msg; Object msgObj = msg.getMessage(); if (msgObj instanceof javax.jms.Message) { javax.jms.Message jmsMsg = (javax.jms.Message) msgObj; if (!hasDuplicate(jmsMsg.getStringProperty(messagePropertyName))) { super.send(producerExchange, msg); } else { sendToDeadLetterQueue(producerExchange.getConnectionContext(), msg); } } } } 

似乎问题中建议的方式,也适用于ActiveMQ(2016/12)。 请参阅activemq-artemis指南。 这要求生产者将特定属性设置到消息中。

 Message jmsMessage = session.createMessage(); String myUniqueID = "This is my unique id"; // Could use a UUID for this message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID); 

但是,包含该属性的类是不同的: org.apache.activemq.artemis.core.message.impl.HDR_DUPLICATE_DETECTION_ID ,属性值为_AMQ_DUPL_ID