Spring integration 带轮询器的Spring集成桥未按预期用于JMS
使用SpringIntegration5.0.7来限制两个JMS队列之间MSG的桥接 文档位于: 建议:Spring integration 带轮询器的Spring集成桥未按预期用于JMS,spring-integration,Spring Integration,使用SpringIntegration5.0.7来限制两个JMS队列之间MSG的桥接 文档位于: 建议: <int:bridge input-channel="pollable" output-channel="subscribable"> <int:poller max-messages-per-poll="10" fixed-rate="5000"/> </int:bridge> 这是一个SpringBoot应用程序,使用JavaDSL配置,
<int:bridge input-channel="pollable" output-channel="subscribable">
<int:poller max-messages-per-poll="10" fixed-rate="5000"/>
</int:bridge>
这是一个SpringBoot应用程序,使用JavaDSL配置,与XML中的配置完全相同(不包括桥接);它很好用
@SpringBootApplication
public class So51792909Application {
private static final Logger logger = LoggerFactory.getLogger(So51792909Application.class);
public static void main(String[] args) {
SpringApplication.run(So51792909Application.class, args);
}
@Bean
public ApplicationRunner runner(JmsTemplate template) {
return args -> {
for (int i = 0; i < 10; i++) {
template.convertAndSend("foo", "test");
}
};
}
@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}
@JmsListener(destination = "bar")
public void listen(String in) {
logger.info(in);
}
}
如您所见,消费者每5秒收到2条消息
调试日志表明队列中没有消息
编辑
我明白了;XML解析器将JmsTemplate receiveTimeout设置为nowait(-1)。因为您没有使用缓存连接工厂,所以我们永远不会收到消息,因为如果客户端()中还没有消息,ActiveMQ客户端将立即返回。由于没有缓存,我们在每次轮询中都会得到一个新的消费者(并且每次都进行无等待接收)
DSL保留JmsTemplate的默认值(无限等待-这实际上是错误的,因为如果没有消息,它会无限期地阻塞轮询器线程)
要修复XML版本,请添加receive timeout=“1000”
修复它
但是,最好使用CachingConnectionFactory
,以避免在每次轮询时创建新的连接/会话/使用者
不幸的是,配置CachingConnectionFactory
会关闭Spring Boot的自动配置。这是
我提出了一个问题来解决DSL和XML之间的不一致性
如果您坚持使用DSL,我建议将接收超时设置为合理的值,而不是不确定的值:
@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.configureJmsTemplate(t -> t.receiveTimeout(1000))
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}
但是,最好的解决方案是使用
CachingConnectionFactory
您不需要桥接器,只需使用一个通道即可。也就是说,它应该可以正常工作。打开调试日志以查看它是否能提供任何线索。我想如果我想在spring集成中处理msg,是的,我不需要桥接到另一个队列……但现在我想保留当前的使用者。在上面的代码中,您只需将入站适配器的通道桥接到出站适配器的通道。这是不必要的;两个适配器可以使用相同的通道;入站适配器的轮询器将直接将消息发送到出站适配器。好的,尝试使用一个通道。没什么区别。我们是否确定使用JmsConnectionFactory在入站通道适配器上支持轮询?如果我使用直接的消息驱动通道适配器,它工作得很好,但当然没有节流;这座桥根本不需要。正如我还说过的,调试日志将向您显示消息传递活动。您是否使用嵌入式ActiveMQ代理进行测试?如果是这样,您可能需要使用CachingConnectionFactory
来避免代理在删除测试消息和轮询之间停止/启动,这可能会导致队列消失。在我的示例中,连接由侦听器保持打开状态。不,它是一个独立的代理,AMQ控制台坚持队列中有东西。如果我将xml流从入站通道适配器更改为消息驱动通道适配器(不带轮询器),它将很好地接收它们。同时,JavaDSL示例可以完美地工作,因此我们将使用这种方法。
@SpringBootApplication
public class So51792909Application {
private static final Logger logger = LoggerFactory.getLogger(So51792909Application.class);
public static void main(String[] args) {
SpringApplication.run(So51792909Application.class, args);
}
@Bean
public ApplicationRunner runner(JmsTemplate template) {
return args -> {
for (int i = 0; i < 10; i++) {
template.convertAndSend("foo", "test");
}
};
}
@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}
@JmsListener(destination = "bar")
public void listen(String in) {
logger.info(in);
}
}
2018-08-10 19:38:52.534 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:52.543 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:57.566 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:57.582 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:02.608 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:02.622 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:07.640 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:07.653 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:12.672 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:12.687 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.configureJmsTemplate(t -> t.receiveTimeout(1000))
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}