java duplicates jms activemq mom

java - Evitar mensajes duplicados en JMS/ActiveMQ



duplicates mom (5)

Ahora hay soporte para eliminar mensajes duplicados incluidos en los transportes ActiveMQ. Consulte los valores de configuración auditDepth y auditMaximumProducerNumber en la Guía de configuración de la conexión .

¿Hay una manera de suprimir los mensajes duplicados en una cola definida en el servidor ActiveMQ?

Intenté definir manualmente JMSMessageID, (message.setJMSMessageID ("uniqueid")), pero el servidor ignora esta modificación y entrega un mensaje con el JMSMessageID integrado.

Por especificación, no encontré una referencia sobre cómo deduplicar mensajes.

En HornetQ, para resolver este problema, debemos declarar la propiedad específica de HQ org.hornetq.core.message.impl.HDR_DUPLICATE_DETECTION_ID en la definición del mensaje.

es decir:

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);

Alguien sabe si hay una solución similar para ActiveMQ?



Dudo que ActiveMQ lo admita de forma nativa, pero debería ser fácil implementar un consumidor idempotente. Una forma de hacer esto sería agregar un identificador único a cada mensaje en el extremo del productor, ahora en el extremo del consumidor usando una tienda (db, caché, etc.), se puede hacer una verificación para ver si el mensaje se ha recibido antes y continuar el proceso basado en esa verificación.

Veo una pregunta de anterior en la misma línea: Apache ActiveMQ 5.3: ¿Cómo configurar una cola para rechazar mensajes duplicados? , eso también puede ayudar.


Hay una manera de hacer que ActiveMQ filtre los duplicados en función de una propiedad JMS. se trata de escribir un Plugin Activemq. Un filtro de intermediario básico que envía mensajes duplicados a la cola del deadletter sería así

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); } } } }


Parece que la forma en que se sugiere en la pregunta, también funciona para ActiveMQ (2016/12). Consulte la activemq-artemis . Esto requiere que el productor establezca una propiedad específica en el mensaje.

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);

Sin embargo, la clase que contiene la propiedad es diferente: org.apache.activemq.artemis.core.message.impl.HDR_DUPLICATE_DETECTION_ID y el valor de la propiedad es _AMQ_DUPL_ID .