Как сохранить порядок сообщений при использовании сообщений из ActiveMQ?

У меня есть служба .NET, которая использует клиент ActiveMQ. Я реализовал MessageListener с транзакционным соединением для приема сообщений.

Иногда я получаю сообщения в другом порядке, в котором они были помещены в очередь.

Было ли неправильно использовать MessageListner? Есть ли способ сохранить порядок сообщений?

К вашему сведению: один производитель помещает сообщения в очередь, а один потребитель извлекает сообщения из очереди.


person HitLikeAHammer    schedule 08.01.2009    source источник
comment
Пожалуйста, просмотрите эту ветку, чтобы получить немного больше информации по проблеме stackoverflow .com / questions / 269363 / activemq-net-client-locks-up.   -  person HitLikeAHammer    schedule 09.01.2009


Ответы (4)


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

Кроме того, есть этот вопрос из < href = "http://activemq.apache.org/faq.html" rel = "nofollow noreferrer"> Часто задаваемые вопросы по ActiveMQ, которые могут помочь.

Изменить: из чтения комментариев к ответ от duffymo, похоже, вы немного переусердствовали. В общем, очереди сообщений, такие как ActiveMQ, MQ Series, joram и т. Д., Имеют две характеристики: они доставляют сообщения в том же порядке, в котором они поставлены в очередь, и они гарантируют доставку сообщений. Отправка отдельного сообщения ACK является избыточной; это немного похоже на фиксацию транзакции базы данных с последующим запросом той же информации, чтобы дважды проверить, действительно ли база данных сохранила ее.

Сказав это, ваш сервер многопоточный? В таком случае он может поставить ответ в очередь до того, как он поставит ACK в очередь.

person Jason Day    schedule 09.01.2009

Дополнительная информация: сервер, который я вызываю, является сторонним, и я не могу контролировать, какие сообщения он отправляет. Я знаю, основываясь на идентификаторах сообщений, что они размещены в правильном порядке. Кроме того, в этой системе есть разница между ACK и подтверждением. ACK получен, когда мое исходное сообщение помещено в «исходящую» очередь. Затем я отслеживаю «входящую» очередь на предмет ответов. Обычно я получаю "Подтверждение", за которым следует "Пройден" или "Не сдан". Идентификатор корреляции для этих сообщений - это идентификатор сообщения из ACK.

Изначально я использовал прослушиватель сообщений и ответил на событие OnMessge. Я отказался от этого подхода после того, как понял, что при использовании этого метода сообщения доставляются асинхронно и, следовательно, в произвольном порядке. Итак, я изменил свой код на опрос с использованием таймера (System.Threading.Timer) для вызова consumer.Receive () и получения одного сообщения за раз. Это работает так, как я хочу.

Я открываю потребителя один раз при запуске службы и постоянно ищу сообщения.

person HitLikeAHammer    schedule 19.01.2009

Почему важен порядок сообщений? MessageListener не должен беспокоиться.

Другое дело, если вам нужен идентификатор корреляции для сопоставления ответа с конкретным запросом. Это то, что вы имели ввиду?

person duffymo    schedule 09.01.2009
comment
Сообщение отправляется на сервер через очередь, и сервер отправляет ответы на это сообщение в другой очереди. Я получаю 2 ответа: сначала сообщение "Подтвердить", затем сообщение "Пройдено" (или "Не пройдено"). У всех одинаковый идентификатор корреляции. Иногда я получаю сообщение с подтверждением в последнюю очередь. - person HitLikeAHammer; 09.01.2009
comment
плохой дизайн, ИМО. ACK звучит так, как будто он должен быть синхронным, не более того, мы получили ваш запрос, и он будет обработан. У меня был бы процессор синхронизации, такой как сервлет, который делал бы это и помещал запрос в очередь. Тогда это всего лишь одна пара req / res, и идентификатор корреляции что-то значит. - person duffymo; 09.01.2009

Все, что только что сказал Джейсон. Еще несколько вещей, о которых следует остерегаться. Вы оставляете потребителя открытым для множества сообщений, верно? Вы не создаете потребителя для нескольких сообщений, а затем закрываете его? Только закрытие потребителя приводит к тому, что сообщения, связанные с потребителем, возвращаются в очередь, что может нарушить порядок.

Это связано с откатами? (Откатываете ли вы какие-либо транзакции?).

Наконец, вы всегда можете обеспечить порядок, используя Resequencer, который изменит порядок вещей за вас.

person James Strachan    schedule 09.01.2009