Прерывистый вызов BridgeHandler и PublishSubscribeChannel, когда канал ответа шлюзов является pub / sub

#spring-integration

#spring-интеграция

Вопрос:

Я вижу странное поведение при отправке данных по моим каналам. Я использую шлюз SI при отправке сообщения, подлежащего обработке. Шлюз настроен, как показано ниже

 <integration:gateway id="rptPubGateway"
    default-request-channel="rptPubInChannel"
    default-reply-channel="rptOutputAvailableChannel"
    default-reply-timeout="60000"
    service-interface="xxxx.RptPubGateway" />
  

Канал ответа настраивается как канал публикации / подписки

 <integration:publish-subscribe-channel id="rptOutputAvailableChannel" />
  

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

 <integration:service-activator input-channel="rptOutputAvailableChannel" ref="requestMessageHandler" method="rptIsDone" output-channel="nullChannel"/>
  

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

  PublishSubscribeChannel - preSend on channel 'rptOutputAvailableChannel'
  

но при сбое последний компонент становится BridgerHandler

 BridgeHandler@e851a798' sending reply Message: 
  

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

Я не уверен, как создается этот BridgerHandler. Из того, что я знаю, этот мост создается для каналов pub / subs, но тогда почему я не вижу его в журнале, когда все работает нормально?

Я был бы признателен за любую помощь

Ответ №1:

Когда вы говорите «сбой», что вы имеете в виду?

На чем работают другие потребители rptOutputAvailableChannel ?

BridgeHandler Вы видите внутренний мост к заголовку сообщения replyChannel , куда в конечном итоге должен идти ответ. При явной отправке rptOutputAvailableChannel всегда вызывается обработчик моста, чтобы получить ответ на временный канал ответа сообщения.

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

1. Как только вызывается BridgeHandler, я получаю ошибку «Исключение ChannelResolutionException: заголовок выходного канала или канала ответа недоступен». rptOutputAvailableChannel имеет а) один клиент-подписчик-активатор службы (см. Мой первоначальный вопрос), который имеет нулевой канал на выходе, б) два других шлюзов, т. Е… default-reply-channel=»rptOutputAvailableChannel»

2. Это означает, что сообщение, отправляемое на канал ответа, потеряло replyChannel свой заголовок. Вы не можете отправлять произвольные сообщения на канал ответа, он должен содержать replyChannel заголовок из входящего сообщения — именно так фреймворк соотносит ответ с запросом. «Два других шлюзов …» — вы не можете иметь несколько шлюзов, использующих один и тот же канал ответа; ответы должны всегда идти к шлюзу, который инициировал поток.

3. Re: «Заголовок replyChannel» , я не отправляю какое-либо произвольное сообщение на свой канал, но я согласен, что каким-то образом эти заголовки теряются. Есть ли какой-либо способ отладить то, что изменяет мое сообщение? Re: «Два других шлюзов» , это разные точки входа для одной и той же полезной нагрузки, т.е. gateway1 принимает в качестве входного XML, в то время как gateway2 вызывается из какой-либо другой службы с той же полезной нагрузкой (XML). В обоих случаях обработка завершает вызов одного и того же активатора службы (вот почему мой replyChannel был объявлен как pub / subs)

4. Правильно, но у вас не может быть нескольких шлюзов с одним и тем же каналом ответа — иначе каждый шлюз получит ответ от запроса. Учитывая способ работы моста, он будет работать нормально, но (в более новых версиях фреймворка) вы будете получать предупреждения о поздних ответах от других экземпляров. Вам было бы намного лучше не объявлять канал ответа и позволить платформе позаботиться о маршрутизации. Просто не включайте output-channel в конечную конечную точку. Включите ведение журнала ОТЛАДКИ, и вы должны увидеть, где replyChannel заголовок теряется.