RabbitMQ-具有手动确认的非阻塞消费者
我刚刚开始学习RabbitMQ,如果我的问题很基本,请原谅我 我的问题实际上与这里发布的问题相同: 然而,经过调查,我发现手动确认会阻止其他消费者从队列阻塞状态获取消息。我想知道怎样才能预防它。下面是我的代码片段RabbitMQ-具有手动确认的非阻塞消费者,rabbitmq,Rabbitmq,我刚刚开始学习RabbitMQ,如果我的问题很基本,请原谅我 我的问题实际上与这里发布的问题相同: 然而,经过调查,我发现手动确认会阻止其他消费者从队列阻塞状态获取消息。我想知道怎样才能预防它。下面是我的代码片段 rabbit提供了一个基础设施,其中一个使用者不能锁定/阻止使用同一队列的其他消息使用者。 您面临的行为可能是以下几个问题的结果: 您没有在频道上使用自动确认模式这一事实会导致您遇到这样的情况:一位消费者接收了该消息,但仍然没有发送批准(基本确认),这意味着计算仍在进行中,使用者可
rabbit提供了一个基础设施,其中一个使用者不能锁定/阻止使用同一队列的其他消息使用者。 您面临的行为可能是以下几个问题的结果:
希望这有帮助。我修改了从队列中获取消息的方式,似乎阻塞问题已经解决。下面是我的代码
public string ReadOneAtTime()
{
Consumer = new QueueingBasicConsumer(Model);
var result = Model.BasicGet(QueueName, false);
if (result == null) return null;
DeliveryTag = result.DeliveryTag;
return Encoding.ASCII.GetString(result.Body);
}
public void Reject()
{
Model.BasicReject(DeliveryTag, true);
}
public void Acknowledge()
{
Model.BasicAck(DeliveryTag, false);
}
回到我最初的问题,我添加了QOS,并注意到其他消费者现在可以获得消息。然而,有些还没有确认,我的程序似乎挂断了。代码更改如下:
public string ReadMessage()
{
Model.BasicQos(0, 1, false); // control prefetch
bool autoAck = false;
Consumer = new QueueingBasicConsumer(Model);
Model.BasicConsume(QueueName, autoAck, Consumer);
_ea = Consumer.Queue.Dequeue();
return Encoding.ASCII.GetString(_ea.Body);
}
public void AckConsume()
{
Model.BasicAck(_ea.DeliveryTag, false);
}
In Program.cs
private static void Consume(Receiver receiver)
{
int counter = 0;
while (true)
{
var message = receiver.ReadMessage();
if (message == null)
{
Console.WriteLine("NO message received.");
break;
}
else
{
counter++;
Console.WriteLine("Received: {0}", message);
receiver.AckConsume();
}
}
Console.WriteLine("Total message received {0}", counter);
}
我感谢你的任何意见和建议。谢谢 我相信,因为我没有调用QOS,而且队列中几乎没有消息,所以代理只向一个消费者发送消息。谢谢你指给我看。然而,当我添加QOS时,我注意到在我发送并运行单个消费者的10条消息中,只有一半是确认消息。消息1、3、5、7、9仅为确认。对此有什么想法吗?请注意您的基本拒绝-您有多个true,可能这就是导致以下情况的原因?我修改并删除了拒绝代码,但仍然无法正常工作。我看到了一些迭代BasicConsume返回值的代码。现在,我将继续使用BasicGet。将消息发布到exchange,而不是直接发布到队列,然后每个消费者使用一个队列可以解决这个问题。
public string ReadMessage()
{
Model.BasicQos(0, 1, false); // control prefetch
bool autoAck = false;
Consumer = new QueueingBasicConsumer(Model);
Model.BasicConsume(QueueName, autoAck, Consumer);
_ea = Consumer.Queue.Dequeue();
return Encoding.ASCII.GetString(_ea.Body);
}
public void AckConsume()
{
Model.BasicAck(_ea.DeliveryTag, false);
}
In Program.cs
private static void Consume(Receiver receiver)
{
int counter = 0;
while (true)
{
var message = receiver.ReadMessage();
if (message == null)
{
Console.WriteLine("NO message received.");
break;
}
else
{
counter++;
Console.WriteLine("Received: {0}", message);
receiver.AckConsume();
}
}
Console.WriteLine("Total message received {0}", counter);
}