Откажитесь от повторяющихся сообщений, только если они все еще находятся в очереди с ActiveMQ Artemis и JBoss EAP 7.1 - PullRequest
0 голосов
/ 24 февраля 2020

Мы используем ActiveMQ Artemis в JBoss EAP 7.1.

Мы заметили, что однажды сообщение с указанным значением c _AMQ_DUPL_ID проходит через очередь, если производитель сообщений пытается отправить сообщение с тем же значением _AMQ_DUPL_ID в ту же очередь снова удаляется посредником. Однако нам нужно отбросить повторяющиеся сообщения, только если они все еще находятся в очереди.

Есть ли способ достичь этой цели?

Мы используем первичный ключ из базы данных как _AMQ_DUPL_ID ценность. Это код, который мы используем

public void sendMessage(final T msg, final String id) { 
   jmsTemplate.send(destination, new MessageCreator() { 
      @Override
      public Message createMessage(Session session) throws JMSException { 
         Message message = session.createObjectMessage(msg);
         message.setStringProperty("_AMQ_DUPL_ID", id);
         return message;
      }
   });
}

Мы ищем решение, потому что у нас есть таймер, который каждые 30 секунд загружает из БД все записи с указанным значением c для status и помещает их в очередь JMS.

Потребители принимают сообщения JMS, обрабатывают их, обновляют свое поле status , вставляют / обновляют их в БД и открывают соединение через веб-сокет с другим приложением что мы не контролируем. Иногда потребитель зависает при вызове веб-сокета и, следовательно, он остается занятым, в то время как таймер продолжает заполнять очередь.

Чтобы решить эту проблему, мы думали, что что-то вроде обнаружения дублирующихся сообщений Artemis поможет. Однако когда внешнее приложение зависает у нашего потребителя, нам нужен таймер, чтобы снова поставить сообщение в очередь.

1 Ответ

0 голосов
/ 24 февраля 2020

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

То, что вы просите здесь, похоже на вопрос, как вставить несколько записей с одним и тем же первичным ключом в таблицу базы данных. Это просто невозможно, потому что весь смысл наличия первичного ключа состоит в том, чтобы избежать дублирования записей.

Я рекомендую вам установить некоторый тайм-аут для вызова websocket, иначе ресурс будет негативно влиять на ваше приложение. Вы не можете контролировать.

Кроме того, вы можете иметь возможность использовать очередь с последними значениями , используя первичный ключ в качестве значения для _AMQ_LVQ_NAME. Это гарантирует, что в любой момент в очереди будет только 1 экземпляр сообщения. Прочитайте документацию для более подробной информации.

...