Можно ли использовать встроенную корреляцию при публикации сообщения в MQ Topic? - PullRequest
3 голосов
/ 10 ноября 2011

Я немного растерялся в использовании тем в WebSphere MQ 7. Предположим, что простой сценарий:

  • У меня есть процесс публикации сообщений в теме.
  • У меня ноль или более подписчиков, получающих сообщение.
  • Любой подписчик может решить отреагировать на полученное сообщение = необязательный «ответ». (Примечание: Первоначально было принято решение использовать темы для ответов, но я при необходимости заменим их на очередь). В опубликованном сообщении может быть настроено ReplyToQueueName или настройка на уровне системы на клиенте.
  • Ответ должен быть соотнесен с исходным опубликованным «запросом» (поскольку может быть более одного опубликованного запроса).

Теперь, как это сделать? Я пытался использовать общий подход из очередей MQ, где инициатор выбирал либо:

  • Установить для отчета значение MQRO_COPY_MSG_ID_TO_CORREL_ID. Получатель примет идентификатор сообщения из запроса и передаст его в качестве идентификатора корреляции в ответ.
  • Установить для отчета значение MQRO_PASS_CORREL_ID + установить идентификатор корреляции в сообщении запроса. Получатель возьмет идентификатор корреляции из запроса и установит его как идентификатор корреляции в ответном сообщении.

В обоих случаях отправителю известно об идентификаторе сообщения или идентификаторе корреляции, переданных в запрос, чтобы он мог правильно сопоставлять сообщения, но это не работает с темами MQ.

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

Вот несколько примеров того, что происходит при использовании тем (идентификаторы в Base64):

Тест с использованием MQRO_COPY_MSG_ID_TO_CORREL_ID:

Send request: // After sending message publisher doesn't know its ID!
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Received request: // Subscriber gets some ID and correlation ID (but publisher didn't set any)
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYH
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYF

Send response:  // Subscriber correctly uses message ID of incoming request
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYH

Received response: // Publisher gets in response completely different IDs!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYP
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYN

Тест с использованием MQRO_PASS_CORREL_ID:

Send request: // Publisher doesn't know its ID but it generated some random correlation ID.
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: Chhv8KT+zhTjfAEdzeiB3cizw9vRy9Pf

Received request: // Subscriber got ANOTHER correlation ID!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYY
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYW

Send response:  // Subscriber is using incorrect correlation ID.
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYW

Received response: // Publisher gets in response completely different IDs!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYg
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYe

Как заставить MQ не изменять мои идентификаторы? Я написал тестовые приложения на Java и .NET, и оба ведут себя одинаково. Или каков правильный подход для моего варианта использования?

Ответы [ 2 ]

2 голосов
/ 11 ноября 2011

Идентификатор сообщения уникален в системе обмена сообщениями. В режиме публикации / подписки механизм обмена сообщениями публикует копию сообщения, отправленного издателем нескольким (и неизвестным) подписчикам. У каждой копии сообщения будет свой идентификатор, так как идентификатор сообщения должен быть уникальным.

Edit:

Прочитайте инфоцентр еще раз, и вот что я нашел.

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

int subOptions = MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INPUT_SHARED | MQC.MQSO_SET_CORREL_ID;
MQTopic sub = qm.AccessTopic(recvQ, "/TEST/CORRELID", null, subOptions);

Необходимо отметить, что MQSO_SET_CORREL_ID нельзя использовать, если вы используете опцию MQSO_MANAGED при создании подписки.

При публикации установите значение корреляции как

putMsg.CorrelationId = Encoding.ASCII.GetBytes("THISISTHECORRELID");
topicCorrelId.Put(putMsg);

При получении публикации вы можете использовать опцию корреляции идентификаторов, например

gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID;
fwdMsg.CorrelationId = Encoding.ASCII.GetBytes("THISISTHECORRELID"); 

sub.Get(fwdMsg, gmo);

Используйте MQMO_MATCH_CORREL_ID только в том случае, если вы используете очередь для нескольких подписок и хотите получать публикации только по определенной теме.

2 голосов
/ 10 ноября 2011

Рассматривали ли вы кодирование с помощью JMS (MQ как реализация) вместо MQ API напрямую?

JMS уже имеет концепцию replyTo в опубликованном сообщении и уже имеет концепцию идентификатора корреляции для связи сообщений.Для replyTo издателем может быть указана очередь или тема, поэтому вы не привязаны ни к принимающей стороне.

...