Сценарий запроса/ответа IBM WebSphere MQ
В настоящее время я работаю над проектом, где мне нужно взаимодействовать с системой IBM, которая взаимодействует с внешним миром через WebSphere MQ. Мне нужно запросить систему в режиме "запрос-ответ", используя очереди, и я буду делать это через диспетчер очереди.
Однако я не могу понять, как это работает на практике.
Скажем, у меня есть несколько экземпляров одного и того же приложения, которое помещает сообщение в очередь запросов. Сообщение выходит из CorrelationId
и MessageId
после выхода из приложения, а свойство ReplyToQueue
устанавливается на каждое сообщение, чтобы убедиться, что диспетчер очереди знает, в какую очередь помещать ответ.
Однако как диспетчер очереди управляет очередью ответов? Нет гарантии относительно сроков ответов, так как получается, что правильный ответ возвращается к экземпляру приложения, который выдал соответствующий запрос?
Я продолжаю думать о очередях сообщений как очередь FIFO, где сообщения должны выбираться один за другим. Однако это означает, что экземпляр A может выбрать ответ, например, B. Очевидно, что это не может быть так, как это работает.
Затем, когда я смотрю на API (com.ibm.mq.MQQueue
), я вижу, что для выбора сообщения у меня есть возможность предоставить CorrelationId
и MessageId
сообщения запроса. Означает ли это, что когда я запрашиваю диспетчер очереди для сообщения (с этим набором идентификаторов), менеджер очереди выполняет итерацию через сообщения в очереди и возвращает соответствующее сообщение? С другой стороны, это означает, что мы не говорим о очереди FIFO?
Ответы
Ответ 1
Общепринятой практикой является использование CorrelationId для связывания сообщений запроса и ответа. Он работает следующим образом:
1) Предположим, что есть две очереди: очередь запросов REQQ, где отправляются сообщения с запросом другого приложения, приложения-службы, для сбора и обработки и RESPQ, к которому приложение-служба помещает ответы.
2) Приложение-запросчик (позвонив ему как REQAPP) помещает сообщение запроса (REQMSG) для запроса очереди (REQQ). Перед отправкой сообщения REQAPP устанавливает свойство ReplyToQ в сообщениях RESPQ. Когда сообщение запроса отправляется, поставщик JMS обновляет отправленное сообщение с помощью уникального MessageId. Приложение-запросчик кэширует этот уникальный MessageId для последующего использования.
3) С другой стороны wold приложение-служба извлекает REQMSG из REQQ, считывает свойство MessageId и ReplyToQ из этого сообщения, обрабатывает запрос и подготавливает соответствующее ответное сообщение RESPMSG. Затем он устанавливает свойство CorrelationId RESPMSG в MessageId, считываемом из REQMSG, и помещает ответ в ReplyToQ.
4) Приложение-запросчик при чтении ответов использует кэши MessageId и устанавливает критерии выбора, как показано ниже, для чтения ответного сообщения
GET MESSAGE FROM RESPQ WHERE RESPMSG.CORRELATIONID==REQMSG.MESSAGEID
Этот критерий выбора гарантирует получение правильных ответов. Ключ здесь - это приложение-служба должно установить CorrelationId в ответе на сообщение MessageId запроса.
Хотя Queue является типом FIFO, реализация MQ обеспечивает доставку сообщений на основе приоритета, когда сообщения с высоким приоритетом доставляются первыми или FIFO, где первое сообщение отправляется поверх очереди. Сообщения также могут быть получены с использованием критериев выбора, как описано в приведенном выше примере.
Надеюсь, что это помогло
Ответ 2
Ответ Shashi используется для многих ситуаций и на самом деле является основным методом распределения ответов среди множества приложений с относительно низким объемом запросов.
Лучший выбор для сервисов большого объема будет включать несколько RESPQ. Вы можете предоставить отдельный RESPQ для каждого экземпляра REQApp, используя временные динамические очереди для получения RESPMsgs - каждый экземпляр REQApp создаст TDQ, используя функцию MQOPEN, и укажет имя RESPQ в атрибуте ReplyToQ каждого отправляемого сообщения,
При такой настройке вам не придется беспокоиться о последовательности и идентификаторах корреляции, так как сообщения будут возвращены отдельным RespQ в том же порядке, в котором они обрабатываются приложением-службой.
Важно отметить, что TDQ - это просто - временное. Когда приложение OPENing закрывает очередь - либо через MQCLOSE, либо путем завершения - любые сообщения в TDQ теряются и не восстанавливаются. Если это проблема - все ответы должны быть обработаны независимо от того, что бы вы хотели, чтобы однократно выделять ряд постоянных динамических очередей (также используя MQOPEN), по одному для каждого экземпляра REQApp, и каждый экземпляр REQApp должен каждый раз подключайтесь к этой же очереди.
Надеюсь, это тоже поможет.