JMS出站网关不适用于请求通道:Dispatcher没有订阅者

时间:2016-06-02 02:49:31

标签: spring-integration spring-jms

我正在使用Spring Integration '4.2.5.RELEASE'

我有一个全局流程集成过程的以下场景(实验目的

  • 从JMS目的地接收数据并发送回复
  • 对收到的数据执行某些操作
  • 将一些数据发送到JMS目的地并收到回复

关于我的第一点,我有以下几点:

<!-- From Remote To Local -->           

<int:channel id="requestFromRemoteToLocalChannel" 
             datatype="com.manuel.jordan.message.Message" />

<int:publish-subscribe-channel id="responseFromRemoteToLocalChannel" 
                               datatype="com.manuel.jordan.message.Message" />

<!-- From Local To Remote -->   

<int:channel id="requestFromLocalToRemoteChannel"                       
             datatype="com.manuel.jordan.message.Message" />

<int:channel id="responseFromLocalToRemoteChannel" 
             datatype="com.manuel.jordan.message.Message" />

<int:channel id="responseFromLocalToRemoteChannelPost" 
             datatype="com.manuel.jordan.message.Message" />

<int-jms:inbound-gateway 
         id="gatewayIn"
         request-destination="queueDestinationFromRemoteToLocal"
         default-reply-destination="queueDestinationFromRemoteToLocalReply"                          
         connection-factory="cachingConnectionFactoryForSpringIntegration"
         request-channel="requestFromRemoteToLocalChannel"
         reply-channel="responseFromRemoteToLocalChannel"
/>

接下来是两个服务激活器

<int:service-activator 
     id="serviceActivatorReceptorFromRemoteToLocal"
     input-channel="requestFromRemoteToLocalChannel"
     output-channel="responseFromRemoteToLocalChannel"
     ref="messageServerReceptorJmsGatewayEndpoint"
     method="receptorFromRemoteToLocal"
                            >
</int:service-activator>

<int:service-activator 
     id="serviceActivatorRemoveReplyFromRemoteToLocal"
     input-channel="responseFromRemoteToLocalChannel"
     output-channel="nullChannel"
     ref="messageServerReceptorJmsGatewayEndpoint"
     method="removeReplyFromRemoteToLocal"
                           >
</int:service-activator>

直到这里一切正常。

通过JmsTemplate我将数据发送到queueDestinationFromRemoteToLocal目的地,因此指向同一目的地的int-jms:inbound-gatewayrequest-destination能够自动获取消息,将其传递给服务激活器并发送对其他JMS目标的回复,并且某些@JmsListener完成其工作。

再次到这里,我很好..

问题是,当我从这个最新的服务激活器发送一些数据到int-jms:outbound-gateway时。它是完成全球整合过程的第三点

只需将最新的服务激活器更改为:

<int:service-activator 
     id="serviceActivatorRemoveReplyFromRemoteToLocal"
     input-channel="responseFromRemoteToLocalChannel"
     output-channel="requestFromLocalToRemoteChannel"
     ref="messageServerReceptorJmsGatewayEndpoint"
     method="removeReplyFromRemoteToLocal"
                           >            
</int:service-activator>

实际上从output-channel="nullChannel"output-channel="requestFromLocalToRemoteChannel"

并补充说:

<int-jms:outbound-gateway 
         id="gatewayOut"
         request-destination="queueDestinationFromLocalToRemote"                              
         reply-destination="queueDestinationFromLocalToRemoteReply"
         connection-factory="selectedConnectionFactory"
         correlation-key="JMSCorrelationID"
         explicit-qos-enabled="true"                        
         delivery-persistent="true"     
         auto-startup="false"               
         request-channel="requestFromLocalToRemoteChannel"
         reply-channel="responseFromLocalToRemoteChannel"

                              >
    <int-jms:reply-listener />

</int-jms:outbound-gateway> 

<int:service-activator 
     id="serviceActivatorRemoveReplyFromLocalToRemote"
     input-channel="responseFromLocalToRemoteChannel"
     output-channel="nullChannel"
     ref="messageServerReceptorJmsGatewayEndpoint"
     method="removeReplyFromLocalToRemote"
                >

</int:service-activator>

启用:

<logger name="org.springframework.integration">
    <level value="debug" />
</logger>

我可以看到:

  

31634 [gatewayIn.container-1] DEBUG o.s.i.j.ChannelPublishingJmsMessageListener $ GatewayDelegate - 网关发生故障sendAndReceive:Dispatcher没有通道'org.springframework.context.annotation.AnnotationConfigApplicationContext@51565ec2.requestFromLocalToRemoteChannel'的订阅者。嵌套异常是org.springframework.integration.MessageDispatchingException:Dispatcher没有订阅者

实际上,int-jms:outbound-gateway 称为

缺少什么?

即使我将requestFromLocalToRemoteChannelDirect更改为Queue并将poller添加到int-jms:outbound-gateway也没有任何反应,上面显示的消息会消失,但是过程仍然被绞死

注意int-jms:outbound-gateway使用auto-startup="false",因为connection-factory="selectedConnectionFactory"缓存)来自:

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(...);
connectionFactory.setClientID("localConnectionFactory");
connectionFactory.setUserName("Manolito - Local");
connectionFactory.createConnection().start();// By This...
connectionFactory.setExceptionListener(new ConnectionFactoryExceptionListener());
return connectionFactory;

其他设置已根据:20.5 Outbound Gateway

使用

如果我使用:

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(...);
connectionFactory.setClientID("localConnectionFactory");
connectionFactory.setUserName("Manolito - Local");
//connectionFactory.createConnection().start();
connectionFactory.setExceptionListener(new ConnectionFactoryExceptionListener());
return connectionFactory;

auto-startup="true"(无论如何我是默认的)我得到了:

  

24917 [gatewayIn.container-1] DEBUG osijChannelPublishingJmsMessageListener $ GatewayDelegate - 网关发生故障sendAndReceive:嵌套异常是javax.jms.InvalidClientIDException:Broker:localhost - 客户端:localConnectionFactory已经从tcp://127.0.0.1连接: 59497

α

添加新

@Bean
@Conditional(value=ActiveMQConnectionFactoryLocalHostStatusCondition.class)
public ActiveMQConnectionFactory localConnectionFactoryForSpringIntegration(
            @Value("${activemq.localhost.protocol}") String protocol,
            @Value("${activemq.localhost.address}") String host,
            @Value("${activemq.localhost.port}") String port) throws JMSException {

        logger.info("Creating localConnectionFactoryForSpringIntegration...");

        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(sameUrl like localConnectionFactory);
        connectionFactory.setClientID("localConnectionFactoryForSpringIntegration");
        connectionFactory.setUserName("Manolito - Local ForSpringIntegration");
        //connectionFactory.createConnection().start();
        connectionFactory.setExceptionListener(new ConnectionFactoryExceptionListener());
        return connectionFactory;
    }

此处,setClientIDsetUserName是新闻,此localConnectionFactoryForSpringIntegration仅用于以下内容: connection-factory="localConnectionFactoryForSpringIntegration"

改变

<int-jms:outbound-gateway 
         id="gatewayOut"
         request-destination="queueDestinationFromLocalToRemote"                              
         reply-destination="queueDestinationFromLocalToRemoteReply"
         connection-factory="localConnectionFactoryForSpringIntegration"
         correlation-key="JMSCorrelationID"
         explicit-qos-enabled="true"                        
         delivery-persistent="true"     
         auto-startup="true"                

         request-channel="requestFromLocalToRemoteChannel"
         reply-channel="responseFromLocalToRemoteChannel"

                              >
    <int-jms:reply-listener />

</int-jms:outbound-gateway> 

我又来了:

  

[gatewayIn.container-1] DEBUG osijChannelPublishingJmsMessageListener $ GatewayDelegate - 网关发生故障sendAndReceive:嵌套异常是javax.jms.InvalidClientIDException:Broker:localhost - 客户端:localConnectionFactoryForSpringIntegration已经从tcp://127.0.0.1:50056连接

直到这里:

  • localConnectionFactorylocalConnectionFactoryForSpringIntegration指向相同的BrokerURL
  • int-jms:outbound-gateway需要非缓存connection-factory
  • localConnectionFactoryForSpringIntegration评论了connectionFactory.createConnection().start()
  • int-jms:outbound-gatewayauto-startup="true"

在某些时候似乎localConnectionFactoryForSpringIntegration已经启动并int-jms:outbound-gateway抛出:

  

localhost - 客户端:已连接tcp://127.0.0.1:50056的localConnectionFactoryForSpringIntegration

似乎需要一些东西

1 个答案:

答案 0 :(得分:0)

消费端点在启动之前不会订阅直接通道(或从队列通道轮询)。因此,当网关处于停止状态(或没有从队列中轮询的任何内容)时,调度程序没有订户。

  

InvalidClientIDException

您无法使用相同的客户端ID创建多个连接;如果您使用不同的连接工厂,则需要唯一的客户端ID。