Spring-amqp listen treads 因未知原因退出。 (原因:尝试使用封闭通道)

Spring-amqp listen treads exits for unknown reason. ( reason: Attempt to use closed channel)

我们运行正在使用 rabbitmq 作为消息传递中间件的许多服务。 当服务正在运行时,我们看到服务停止侦听请求,需要我们重新启动服务以使其再次运行。 我们运行同一个JVM(Oracle Weblogic应用服务器)上的多个服务,但并不是所有的服务都停止,通常只有一个,但并不总是同一个。

它似乎与负载无关,因为服务具有非常不同的负载配置文件。

我们设置了心跳协议,但是并没有解决问题。由于我们的测试环境也出现了这个问题,所以我们将日志级别设置为调试,希望这能揭示原因并提示解决方案。

遗憾的是,它没有,或者我们对发生的事情缺乏了解(对 spring-amqp 和 amqp 库不太熟悉,但我们阅读了 spring 文档)。

我们在日志中看到以下异常,之后没有任何反应,直到我们重新启动服务:

;2015-05-08 00:35:54,578; DEBUG; servicename=; clusterid=; username=; msguuid=; org.springframework.amqp.rabbit.core.RabbitAdmin - Declarations finished
;2015-05-08 00:37:12,015; ERROR; servicename=; clusterid=; username=; msguuid=; nl.pharmapartners.amqp.connectors.AmqpMessageListenerContainer - Consumer received fatal exception on startup
;org.springframework.amqp.rabbit.listener.FatalListenerStartupException: Authentication failure
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:367)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:963)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.PossibleAuthenticationFailureException: Possibly caused by authentication failure
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:57)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:195)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:359)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createBareChannel(CachingConnectionFactory.java:309)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.getCachedChannelProxy(CachingConnectionFactory.java:283)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.getChannel(CachingConnectionFactory.java:276)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.access0(CachingConnectionFactory.java:69)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$ChannelCachingConnectionProxy.createChannel(CachingConnectionFactory.java:614)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createChannel(ConnectionFactoryUtils.java:85)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:134)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:67)
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:363)
    ... 2 more
Caused by: com.rabbitmq.client.PossibleAuthenticationFailureException: Possibly caused by authentication failure
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:373)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:516)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:545)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:191)
    ... 12 more
Caused by: com.rabbitmq.client.AlreadyClosedException: clean connection shutdown; reason: Attempt to use closed channel
    at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:223)
    at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:209)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:202)
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:355)
    ... 15 more
2015-05-08 00:37:12,032; ERROR; servicename=; clusterid=; username=; msguuid=; nl.pharmapartners.amqp.connectors.AmqpMessageListenerContainer - Stopping container from aborted consumer

我们不知道发生了什么,在此之前我们看到交换、队列和绑定大约每分钟都在重新声明。此日志在重新声明完成后约 1.5 分钟出现。 没有日志表明 rabbitmq 有问题,所以我们不知道所报告的尝试使用已经关闭的连接的任何线索。这全部来自 amqp-client 或 spring-amqp 库。

我在rabbit集群上没有找到相关的错误日志,只在/var/log/rabbitmq目录下找了

日志似乎表明存在身份验证问题,但是在同一节点上使用相同身份验证参数的其他服务 运行ning 没有问题(服务本身已经 运行ning 相当while (up to days) 也没有任何问题。最初的异常表明图书馆获得了一个新频道,但它已经关闭,无法使用。

有人可以解释发生了什么以及如何解决这个问题吗?

我们 运行ning RabbitMQ 3.3.3/Erlang 17 Spring amqp 版本 1.3.2,amqp-client 3.2.4。

附加信息: 我们正在使用默认值配置各种组件,但以下情况除外:

#The waiting time (ms) for a response in amqp (for rpc calls)
amqp.timeout=30000
prefetch.count=1
max.concurrent.consumers=5
start.consumer.min.interval=500
stop.consumer.min.interval=5000
consecutive.active.trigger=3
consecutive.idle.trigger=3
amqp.message.ttl=900000
amqp.heartbeat=5

RabbitMQ 有一项政策会删除超过 120 秒没有消费者的队列。所有队列都镜像到兔子集群中的所有节点(3 个节点)。

我们已经发现我们使用了一个 CachingConnectionFactory,它的默认缓存大小为 1(我们将更改它,因为这似乎不适合 5 个并发消费者,我们认为这应该至少等于最大值消费者)。

提前致谢,

Wim Veldhuis。

正如我在 rabbitmq-users 组所说,这个 "channel" 是一个内部特殊通道,用于验证新连接。

Caused by: com.rabbitmq.client.PossibleAuthenticationFailureException: Possibly caused by authentication failure
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:373)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:516)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:545)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:191)
    ... 12 more
Caused by: com.rabbitmq.client.AlreadyClosedException: clean connection shutdown; reason: Attempt to use closed channel
    at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:223)
    at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:209)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:202)
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:355)
    ... 15 more

如您所见,我们正在尝试创建新连接

com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:545)
    at     org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:191)

大概是因为现有连接因某种原因关闭了。

而且这个异常发生在认证过程中; Spring AMQP 从未重新获得控制权。

再说一次,正如我在群里所说,你需要查看rabbitmq-server日志,看看那里是否有任何线索。

缓存与消费者渠道无关 - 它们无论如何都不符合缓存条件(自 1.1.3 起)。

编辑:

我们将用户请求后的身份验证错误更改为致命错误,在 1.2.1 中,作为用户请求的结果(如果凭据错误,继续尝试没有意义)。

但是,rabbitmq-client 中似乎存在竞争条件,因为如果连接在打开后立即关闭(在身份验证之前),则报告为 PossibleAuthenticationFailureException.

我们可以添加一个选项将 PossibleAuthenticationFailureException 视为非致命(并继续尝试)。欢迎打开JIRA issue,我们一起来看看。