Spring Integration JMS/IBM MQ: как параллельно отправлять разные сообщения в разные очереди

#spring-integration #ibm-mq #spring-jms

Вопрос:

Я работаю с проектом, который использует прослушиватель JMS для приема входящего сообщения, а затем направляет его в другое место назначения, в настоящее время процесс выбирает только одно место назначения из 3 ниже для каждого входящего сообщения. таким образом, конфигурация xml записывается следующим образом

 <integration:router ref="jmsRouter" input-channel="jmsFilterOutput" default-output-channel="jmsRouterOutput"  />

<integration:service-activator id="serviceActivator1" input-channel="input1"
                               ref="messageProcessService" method="callMsgProcessor1" />
                               
<integration:service-activator id="serviceActivator2" input-channel="input2"
                               ref="messageProcessService" method="callMsgProcessor2" />

<integration:service-activator id="serviceActivator3" input-channel="sharedInput"
                               ref="messageProcessService" method="callMsgProcessor3" output-channel="reqChannel" />
 

среди вышеперечисленных 3 ServiceActivator выходной канал последнего определен как IBM mq в другом файле конфигурации xml.

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

поэтому я добавляю строку, как показано ниже

 <integration:service-activator id="serviceActivator4" input-channel="sharedInput"
                                   ref="messageProcessService" method="callMsgProcessorNew" output-channel="reqChannelNew" />
 

однако при запуске JMS сообщение из sharedInput отправляется только в callMsgProcessor3, а заполненное сообщение также отправляется только в канал reqChannel и игнорирует мое новое назначение. если я закомментирую третий активатор службы, sharedInput может перейти в callMsgProcessorNew и перенаправить в новую очередь.

может ли кто-нибудь посоветовать, как я должен настроить, чтобы общий вход передавался двум процессорам (callMsgProcessor3 и callMsgProcessorNew), а также параллельно отправлялся на соответствующий выходной канал mq?

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

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

Ответ №1:

Вы можете создать sharedInput канал подписки на публикацию и подписаться на него другим активатором службы, чтобы одно и то же сообщение отправилось им обоим. После этого вы можете создавать абсолютно разные потоки и выполнять любую логику, которую вам нужно параллелизировать. Дополнительную информацию смотрите в документах: https://docs.spring.io/spring-integration/docs/current/reference/html/core.html#channel-implementations-publishsubscribechannel.

Также соответствующее определение EIP : https://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html

Комментарии:

1. Спасибо! Я могу использовать маршрутизатор списка получателей для решения этой проблемы. 🙂

Ответ №2:

спасибо за ваш ответ, @Artem! Я понял одну вещь: общий ввод идет только в одно место назначения, потому что это одно сообщение. если я смогу продублировать сообщение, оно отправится в два пункта назначения. поэтому я добавил маршрутизатор списка получателей и внес изменения, как показано ниже, и это сработало!

 <integration:recipient-list-router id="duplicateMsgRouter" input-channel="sharedInput"
    timeout="1234"
    ignore-send-failures="true"
    apply-sequence="true">
    <integration:recipient channel="channel1"/>
    <integration:recipient channel="channel2"/>
</integration:recipient-list-router> 

<integration:service-activator id="serviceActivator3" input-channel="channel1"
                               ref="messageProcessService" method="callMsgProcessor3" output-channel="reqChannel" />

<integration:service-activator id="serviceActivator4" input-channel="channel2"
                               ref="messageProcessService" method="callMsgProcessorNew"  output-channel="reqChannelNew" />