是否有针对RabbitMQ消息的超时?

Voj*_*h B 10 c# rabbitmq

我想设置一个超时,之后一个出列的消息自动被NACK.

当我将消息出列时,我等到它被转移到套接字上,而另一方确认其接收.

我是否需要保留计时器列表,还是RMQ可以自动处理?

private void Run()
{
    _rmqConnection = _queueConnectionFactory.CreateFactory().CreateConnection();

    _rmqReadchannel = _rmqConnection.CreateModel();

    _rmqReadchannel.QueueDeclare(QueueIdOutgoing(), true, false, false, null);

    _rmqReadchannel.BasicQos(0, 1, false);
    var consumer = new QueueingBasicConsumer(_rmqReadchannel);
    _rmqReadchannel.BasicConsume(QueueIdOutgoing(), false, consumer);
    while (true)
    {
        if (!_rmqReadchannel.IsOpen)
        {
            throw new Exception("Channel is closed");
        }
        var ea = consumer.Queue.Dequeue();
        string jsonData = Encoding.UTF8.GetString(ea.Body);
        if (OnOutgoingMessageReady != null)
        {
            OnOutgoingMessageReady(this, new QueueDataEventArgs(jsonData, ea.DeliveryTag));
        }
        //waiting for ACK from a different thread
    }
}
Run Code Online (Sandbox Code Playgroud)

Don*_*nut 21

RabbitMQ不提供任何类型的超时机制来确认消息.这在官方Python教程中讨论:

没有任何消息超时; 只有当工作者连接死亡时,RabbitMQ才会重新传递消息.即使处理消息需要非常长的时间,也没关系.

AMQP 0-9-1规范的第3.1.8节描述了致谢,并且非常清楚它们可以是自动的(客户端不必做任何事情,消息一旦被传递就被确认)或显式(对于已处理的每条消息或消息组,客户端必须是Ack.

这是2009年以后的一些过去的讨论,证实了这种情况.

所以:是的,如果你需要超时以在一段时间后自动发送NACK,你必须自己这样做.

  • 在不反对这个答案的有效性的情况下(在发布时是正确的),自那时起,RabbitMQ 的新版本已经实现了“消费者确认超时”(默认为 30 分钟),并严格执行。请参阅上面@Egor 的回答。 (3认同)
  • @leonidos79 感谢您指出这一点;我更新了我的答案,以考虑当前的行为以及默认行为随着时间的推移而改变的事实。 (2认同)

Ego*_*gor 17

现代版本的 RabbitMQ 有ack timeout。因此,如果您的消费者在确认交货之前花费了大量时间,请谨慎更新新版本。

如果消费者在超过超时值(默认为 30 分钟)的时间内没有确认其交付,则其通道将被关闭,并出现 PRECONDITION_FAILED 通道异常。

UPD: 更新的文档包含禁用超时的说明:

可以使用advanced.config 停用超时。不推荐这样做:

%% advanced.config
[
  {rabbit, [
    {consumer_timeout, undefined}
  ]}
].
Run Code Online (Sandbox Code Playgroud)

不要完全禁用超时,而是考虑使用较高的值(例如几个小时)。