RabbitMQ:查找由于消费者异常而导致通道关闭的原因
Posted
技术标签:
【中文标题】RabbitMQ:查找由于消费者异常而导致通道关闭的原因【英文标题】:RabbitMQ: find reason for channel shutdown due to consumer exception 【发布时间】:2018-09-27 12:38:55 【问题描述】:我有一个使用 RabbitMQ Java client library 创建的 RPC 服务器,在使用消息时出现以下错误:
com.rabbitmq.client.ShutdownSignalException: clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=Closed due to exception from Consumer (amq.ctag-CAqHaJnRsaP6dfo***R8lw) method handleDelivery for channel AMQChannel(amqp://guest@127.0.0.1:5672/,1), class-id=0, method-id=0)
at com.rabbitmq.client.impl.ChannelN.close(ChannelN.java:588)
at com.rabbitmq.client.impl.ChannelN.close(ChannelN.java:541)
at com.rabbitmq.client.impl.StrictExceptionHandler.handleChannelKiller(StrictExceptionHandler.java:72)
at com.rabbitmq.client.impl.StrictExceptionHandler.handleConsumerException(StrictExceptionHandler.java:61)
at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:154)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
但是,这只有在我对 RPC 客户端实现进行某些更改时才会发生,否则 RPC 服务器可以正常工作。无论是否发生错误,客户端发送的消息始终相同。
RabbitMQ 日志没有提及任何有关通道关闭的信息。
如何更详细地了解频道关闭和消费者异常的原因是什么?
编辑
这是创建连接、通道和消费者的代码。没有其他人使用此通道,并且每当从REQUEST_QUEUE
向此代码传递消息时,就会发生上述错误。
public static void main(String[] args)
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try
Connection connection = factory.newConnection();
channel = connection.createChannel();
channel.queueDeclare(REQUEST_QUEUE, false, false, true, null);
channel.basicConsume(REQUEST_QUEUE, true, RpcServer::onMsgReceived, RpcServer::onCancel);
channel.addShutdownListener(new ShutdownListener()
@Override
public void shutdownCompleted(ShutdownSignalException cause)
cause.printStackTrace();
);
System.out.println("Waiting for RPC requests");
catch (IOException | TimeoutException e)
e.printStackTrace();
【问题讨论】:
如果您能提供异常发生时您正在做什么的详细信息,将会更有帮助。我同意该日志中的信息不是很有帮助。 能否在代码中注明是否有专门用于消费的渠道,或者是否以不同的方式使用相同渠道? 我在问题中发布了代码。该频道仅供该消费者使用。代码很简单,我用过很多次都没有问题。该问题仅与将消息发送到队列(RPC 客户端)的特定代码结合使用。 我在使用最后一个 4.x Java 客户端时发生了同样的事情。当我有多个消费者运行时,它似乎会发生。两个将关闭,一个将继续运行而不会出现问题。如果我运行五个消费者进程(不是线程),两个很快就会死掉,而其他的会运行一段时间。我从来没有让他们全部死去。我在调试会话中跟踪了代码,并在句柄方法正常结束后以异常关闭退出。 【参考方案1】:这可能是因为您的连接默认配置为使用com.rabbitmq.client.impl.StrictExceptionHandler。
如果您不想在出现异常时关闭通道,您可能需要编写自己的异常处理程序,或者使用com.rabbitmq.client.impl.ForgivingExceptionHandler。
还要注意默认情况下连接将使用com.rabbitmq.client.impl.DefaultExceptionHandler,它扩展了com.rabbitmq.client.impl.StrictExceptionHandler。
还有一件事。您可以使用 setExceptionHandler 方法在连接工厂中设置异常处理程序。
【讨论】:
以上是关于RabbitMQ:查找由于消费者异常而导致通道关闭的原因的主要内容,如果未能解决你的问题,请参考以下文章