我想设置一个超时,之后一个出列的消息自动被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,你必须自己这样做.
Ego*_*gor 17
现代版本的 RabbitMQ 有ack timeout。因此,如果您的消费者在确认交货之前花费了大量时间,请谨慎更新新版本。
如果消费者在超过超时值(默认为 30 分钟)的时间内没有确认其交付,则其通道将被关闭,并出现 PRECONDITION_FAILED 通道异常。
UPD: 更新的文档包含禁用超时的说明:
可以使用advanced.config 停用超时。不推荐这样做:
%% advanced.config
[
{rabbit, [
{consumer_timeout, undefined}
]}
].
Run Code Online (Sandbox Code Playgroud)
不要完全禁用超时,而是考虑使用较高的值(例如几个小时)。