首页 > 解决方案 > Spring:单线程消费者

问题描述

一些工作人员(侦听器)必须以单线程方式一一处理消息。(是的,这是弱点,我知道。)看起来,我不知道如何正确设置它。应用程序挂在 Spring5 上,这阻止了我从 Spring4 移动。

我想强调:应用程序应该有多个单线程侦听器。一个队列一个监听器。我的意思是一些 . 一个队列没有多个侦听器。

我使用科特林。但问题在于配置甚至库错误。

@RabbitListener(
        queues = [(queueName1)],
        containerFactory = "exclusiveListenerContainerFactory"
    )
fun handle1(...

@RabbitListener(
        queues = [(queueName2)],
        containerFactory = "exclusiveListenerContainerFactory"
    )
fun handle2(...

@Bean
open fun exclusiveListenerContainerFactory(
    connectionFactory: ConnectionFactory,
    messageConverter: MessageConverter
): SimpleRabbitListenerContainerFactory {
    val factory = SimpleRabbitListenerContainerFactory()
    factory.setConnectionFactory(connectionFactory)
    factory.setConcurrentConsumers(1)
    factory.setMessageConverter(messageConverter)
    factory.setDefaultRequeueRejected(false)
    return factory
}

我对每种监听器都使用了SINGLE ExclusiveListener Container Factory。
SINGLE rabbit Connection Factory(CachingConnectionFactory 的实例)
我不知道是不是这样。

麻烦的是:

有时应用程序在 Spring5 上挂起。在 Spring 4 上,相同的配置运行良好。有趣的是,它在机器上使用了 KVM 虚拟化。即使使用 Spring5,Virtualbox 也能很好地工作。

jstack https://pastebin.com/MXdHcVAK
top -H -p 显示 PID 42 消耗所有 cpu

前段时间,我尝试迁移到 Spring5,但遇到了同样的麻烦。我以为是 reactor-netty lib 问题,但没有运气,他们无法重现https://github.com/reactor/reactor-netty/issues/381

我认为这两件事 - 配置和悬挂 - 是绑定的。但我无法深入。

更新

关于转储:如果我理解一切正确(我不确定),"tcp-client-loop-nio-4" #24 daemon prio=5 os_prio=0 tid=0x00007fc0de44d800 nid=0x2a runnable则 jstack 中的条目消耗的 cpu。但我不知道该怎么办。

更新2

Spring Integration 和 Spring AMQP 的首席开发人员 - @GaryRussell - 批准此配置。所以我认为这个问题是关于netty的。

更新3

此问题已通过 netty 版本升级修复。

标签: nettyspring-rabbitreactor-netty

解决方案


推荐阅读