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:查找由于消费者异常而导致通道关闭的原因的主要内容,如果未能解决你的问题,请参考以下文章

WSO2 rabbitMQ - 创建但未关闭的通道 - 内存泄漏问题

初尝RabbitMQ消息队列

RabbitMQ 消费预取数量的优化

rabbitmq队列中消息过期配置

confluence异常关闭恢复

rabbitmq 重复ACK导致消息丢失