rabbitmq中客户端30分钟未ack报错解决

文章讲述了在使用RabbitMQ客户端时遇到的AlreadyClosedException异常,原因是消息确认超时,导致连接被服务端关闭。解决方案是配置消费者的确认超时时间,特别是对于Docker环境,需要在配置文件中设置。当消息确认超时时,所有未处理的消息会被退回服务端。此异常若未正确处理会导致服务宕机,需捕获异常并重新建立MQ连接。

异常复现/错误日志

错误日志

Unhandled exception. RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text='PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more', classId=0, methodId=0

ERROR MESSAGE

ack failed,Exception=Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text='PRECONDITION_FAILED - deli
very acknowledgement on channel 1 timed out. Timeout value used: 60000 ms. This timeout value can be configured, see consumers doc guide to learn more', classId=0, methodId=0

这个错误发生在 RabbitMQ 客户端,提示连接已经被关闭,并给出了关闭的原因:

  • close-reason,由对等方(Peer)发起;
  • code=406,表示 PRECONDITION_FAILED;
  • text=‘PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more’,说明是因为一个名为“channel 1”的通道上的消息确认超时了,并且在规定的时间内没有得到确认。在这里,超时值为 1800000 毫秒(30 分钟)。

通俗解释就是:你的消息超时未处理,rabbbitmq服务端认为你这个客户端是有问题的,服务端已经踢出了你这个客户端,注意是整个客户端,connect连接都没了哦!

那么如何解决呢,只要配置ack的超时时间即可,官方说明:
https://www.rabbitmq.com/consumers.html#acknowledgement-timeout

如果你是docker环境,那么有一点坑,就是通过环境变量所配置的consumer_timeout 是不生效的,如下:

version: "3"
services:
  rabbitmq:
    image: rabbitmq:3.8-management-alpine
    environment:
      - RABBITMQ_CONSUMER_TIMEOUT=600000 # 设置consumer_timeout参数为600000毫秒

需要在配置文件中动态设置参数:

version: "3"
services:
  rabbitmq:
    image: rabbitmq:3.8-management-alpine
    volumes:
      - ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
    environment:
      - RABBITMQ_CONFIG_FILE=/etc/rabbitmq/rabbitmq.conf

在rabbitmq.conf文件中,设置consumer_timeout参数。如下:

default_pass = guest
default_user = guest
default_vhost = /
consumer_timeout = 600000

常见问题:

  • 如果我这个客户端有n条消息还没处理完或者正在处理,只有一条超时了,那么其余n-1消息怎么办?

答:一条消息超时后mq服务端就会认定你这个client是有问题的,mq服务端会直接断开与你这个client的连接,也就是说不管你这个client还有多少条消息,都会被送回mq的服务端,将被投递到别的客户端或者等待下次投递。

  • 该错误是否会使我的服务宕机?

答:是的,如果未正确处理异常会使服务异常关闭。如果处理了异常,也会导致mq不可用(无法接收消息,因为connect已经关闭),正确处理方式是处理异常并重新连接MQ(初始化操作)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L-960

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值