我正在使用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-gateway
通过request-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.contaner-1]DEBUG o.s.i.j.ChannelPublishingJmsMessageListener$GatewayDelegate-网关sendAndReceive中发生故障:调度程序没有通道的订阅者org.springframework.context.annotation.AnnotationConfigApplicationContext@51565ec2.requestFromLocalToRemoteChannel’。;嵌套异常为org.springframework.integration.MessageDispatchingException:Dispatcher没有订阅者
实际上int-jms:outbound-gateway
是而不是称为
缺少什么?
即使我将requestFromLocalToRemoteChannel
从Direct
更改为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出站网关使用了其他设置
如果我使用:
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.contaner-1]调试o.s.i.j.ChannelPublishingJmsMessageListener$GatewayDelegate-网关sendAndReceive中发生故障:嵌套异常为javax.jms.InvalidClientIDException:Broker:localhost-Client:localConnectionFactory已从连接tcp://127.0.0.1:59497
Alpha
添加新
@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;
}
这里,setClientID
和setUserName
是新闻,此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.contaner-1]DEBUG o.s.i.j.ChannelPublishingJmsMessageListener$GatewayDelegate-网关sendAndReceive中发生故障:嵌套异常为javax.jms.InvalidClientIDException:Broker:localhost-Client:localConnectionFactoryForSpringIntegration已从连接tcp://127.0.0.1:50056
在此之前:
- 我有指向同一
BrokerURL
的localConnectionFactory
和localConnectionFactoryForSpringIntegration
int-jms:outbound-gateway
需要一个未缓存的connection-factory
localConnectionFactoryForSpringIntegration
已评论connectionFactory.createConnection().start()
int-jms:outbound-gateway
具有auto-startup="true"
似乎在某个时刻localConnectionFactoryForSpringIntegration
已经启动,并且int-jms:outbound-gateway
抛出:
localhost-Client:localConnectionFactoryForSpringIntegration已从连接tcp://127.0.0.1:50056
似乎需要一些东西,它是
消费端点在启动之前不会订阅直接通道(或从队列通道轮询)。因此,当网关处于停止状态(或者没有从队列中轮询任何内容)时,调度器没有订阅者。
InvalidClientIDException
不能使用相同的客户端id创建多个连接;如果使用不同的连接工厂,它们需要唯一的客户端id。