我的Spring Integration应用程序使用RabbitMQ中的消息,将它们转换为SOAP消息,并进行Web服务请求。
每秒可以从队列中获取许多(10 – 50)消息。 或者在应用程序重新启动后,RabbitMQ队列中可能有数千条消息。
在并行线程中最多处理10条消息的最佳方案是什么(消息排序很高兴具有但不是必需的功能,如果Web服务回答业务失败,则失败的消息应重试,直到成功为止)。 / p>
Amqp侦听器不应使用队列中的更多消息,因为任务执行程序中没有可用的繁忙线程。 我可以在这样的频道中定义ThreadExecutor:
@Bean
public AmqpInboundChannelAdapterSMLCSpec
amqpInboundChannelAdapter(ConnectionFactory connectionFactory, Queue queue)
{
return Amqp.inboundAdapter(connectionFactory, queue);
}
IntegrationFlow integrationFlow = IntegrationFlows
.from(amqpInboundChannelAdapter)
.channel(c -> c.executor(exportFlowsExecutor))
.transform(businessObjectToSoapRequestTransformer)
.handle(webServiceOutboundGatewayFactory.getObject())
.get();
或者像这样在AmqpInboundChannelAdapter中定义一个任务执行程序,并且不在流定义中定义通道任务执行程序就足够了:
@Bean
public AmqpInboundChannelAdapterSMLCSpec
amqpInboundChannelAdapter(ConnectionFactory connectionFactory, Queue queue)
{
return Amqp.inboundAdapter(connectionFactory, queue)
.configureContainer(c->c.taskExecutor(taskExecutor));
}
或者为选项1之类的通道定义任务执行器,但还需要在通道适配器上设置maxConcurrentConsumers,如下所示:
@Bean
public AmqpInboundChannelAdapterSMLCSpec
amqpInboundChannelAdapter(ConnectionFactory connectionFactory, Queue queue)
{
return Amqp.inboundAdapter(connectionFactory, queue)
.configureContainer(c->c.maxConcurrentConsumers(10));
}
答案 0 :(得分:2)
在concurrency
上配置ListenerContainer
并让所有下游进程在容器中的那些线程上发生的最佳实践。这样,当由于线程繁忙而从队列中不再轮询任何消息时,您将获得自然的背压。另一方面,不会因为仅在侦听器容器之后使用ExecutorChannel
而释放消息线程,并且当前消息将被确认为已消耗,但不会在下游失败