Предотвращение дублирования сообщений на ОМС/в частности, ActiveMQ

есть способ подавить дублированные сообщения в очереди, определенной на сервере ActiveMQ?

Я попытался определить вручную JMSMessageID, (сообщение.setJMSMessageID ("uniqueid")), но сервер игнорирует эту модификацию и доставляет сообщение со встроенным сгенерированным JMSMessageID.

по спецификации я не нашел ссылку о том, как дедуплицировать сообщения.

в HornetQ, чтобы справиться с этой проблемой, нам нужно объявить конкретное свойство HQ орг.hornetq.ядро.сообщение.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?

5 ответов


вы должны посмотреть на Apache Camel, он предоставляет идемпотентный потребительский компонент, который будет работать с любым поставщиком JMS, см.:http://camel.apache.org/idempotent-consumer.html

использование этого в сочетании с компонентом ActiveMQ делает использование JMS довольно простым, см.: http://camel.apache.org/activemq.html


Я сомневаюсь, что ActiveMQ поддерживает его изначально, но это должно быть легко реализовать идемпотентного потребителя. Способ сделать это-добавить уникальный идентификатор к каждому сообщению в конце производителя, теперь в конце потребителя, используя хранилище(БД, кэш и т. д.), Можно проверить, было ли сообщение получено раньше и продолжить обработку на основе этой проверки.

Я вижу предыдущий вопрос stackoverflow по тем же строкам - Apache ActiveMQ 5.3 - как настроить очередь для отклонения повторяющихся сообщений? , что также может помочь.


теперь есть поддержка удаления дубликатов сообщений, запеченных в транспортах ActiveMQ. См. значения конфигурации auditDepth и auditMaximumProducerNumber на Руководство По Конфигурации Подключения.


существует способ сделать ActiveMQ фильтровать дубликаты на основе свойства JMS. он включает в себя написание Activemq плагин. Базовый фильтр брокера, который отправляет повторяющиеся сообщения в очередь deadletter, будет выглядеть следующим образом

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.