bigywater.tech
RabbitMQ · 24

消费者超时:consumer_timeout

消费者拿了消息却不确认(处理卡死、死循环),消息会被一直占着。consumer_timeout 是 RabbitMQ 的兜底。它默认多久、怎么按队列覆盖、真的会在超时后关掉 channel 吗?这篇如实记录能验证的和没验证到的。

1800000 ms
consumer_timeout 的默认值(30 分钟)
406
经典队列声明 x-consumer-timeout 的错误码;quorum 队列接受
420 s
超时配成 10 s,等 7 分钟 channel 仍没被关——这一篇没验证到“超时关闭”

默认值与配置

实测 · 本机执行输出
  不改配置的节点:  $ rabbitmqctl eval "application:get_env(rabbit, consumer_timeout)."  →  {ok,1800000}
  改了配置的节点:  同样的命令  →  {ok,10000}

默认 consumer_timeout 是 1800000 ms(30 分钟),可在 rabbitmq.conf 里设置;rabbitmqctl eval 能读到当前值。

按队列覆盖

实测 · 本机执行输出
  经典队列带 x-consumer-timeout=2000:  ChannelClosedByBroker: (406, "PRECONDITION_FAILED - invalid arg 'x-consumer-timeout' for queue 'ctc' in vhost '/' of queue type rabbit_classic_queue")
  quorum 队列带 x-consumer-timeout=2000:  成功
  $ rabbitmqctl set_policy ct-pol "^ctp$" '{"consumer-timeout":3000}' --apply-to queues  →  ol" for pattern "^ctp$" to "{"consumer-timeout":3000}" with priority "0" for vhost "/" ...
  list_policies: / | ct-pol | ^ctp$ | queues | {"consumer-timeout":3000} | 0

quorum 队列接受队列参数 x-consumer-timeout,经典队列返回 406 invalid arg;policy consumer-timeout 都可以设置。

没验证到的部分

实测 · 本机执行输出
  ct.classic: 420 s 内 channel 没有被关;此时队列 (ready, unacked) = (0, 1)
  ct.quorum: 420 s 内 channel 没有被关;此时队列 (ready, unacked) = (1, 0)
  broker 日志里和消费者超时有关的行: ["<0.1032.0> operation queue.declare caused a channel exception precondition_failed: invalid arg 'x-consumer-timeout' for queue 'ctc' in vhost '/' of qu"]
  结论(仅限这次实验):consumer_timeout=10 s 的配置读到了,可是 7 分钟内没有观察到 broker 因为未确认而关闭 channel;我没有找到原因——文档说这个检查是周期性的(以分钟计),可是 7 分钟已经跨过了好几个周期

把超时配成 10 秒,消费者收到消息后不确认,等了 7 分钟,channel 没有被关,日志里也没有相关记录。可能是这个检查的触发条件我没有满足,也可能是 4.3.6 的行为与我预期不同——这里没有查清,所以不写“超时之后一定会怎样”。

分步演示

消费者超时
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / RabbitMQ 4.3.6 / Erlang/OTP 28.5 / pika 1.4.4(Homebrew 与临时虚拟环境);所有节点都是本机自己起的 RabbitMQ 进程(127.0.0.1,端口 9500 以上,每个实验独立的数据目录与节点名,不连任何外部服务);命令输出来自真实的 rabbitmqctl 与管理 API,发布与消费用 pika 的真实连接;计时用 time.perf_counter,数字每次运行会有小幅抖动。参数 / policy 的验证是真实的声明与 set_policy;第三节的消费者用 pika,prefetch=10,不 ack,心跳 60 s,经典队列与 quorum 队列各一个,等 420 秒,期间观察 channel 的 close 回调与 rabbitmqctl list_queues
    • 没有验证:超时真的触发时的错误文本、被终止的 channel 上未确认消息的去向(回队列并 redelivered)、检查的周期;为什么 10 s 的配置在 7 分钟内没有生效;更长时间(超过 7 分钟)的观察;AMQP 1.0 消费者;前两次更早的实验(240 秒、170 秒)也同样没有看到 channel 被关
    京ICP备2026067502号-1京公网安备11010502063487号