RabbitMQ - 了解消费者的情况

时间:2016-03-18 20:00:43

标签: c# rabbitmq

我在RabbitMQ中有一些关于编码的问题......我不是这个世界的新手,并且根据我提供给我实施的设计提出了问题......

  • 如果我从Consumer发送BasicAck或BasicAack,它是否仅删除 来自队列的相应消息或将它传递给Ack 出版商?
  • 如何确保发布服务器仅在消费者准备好处理时才向服务器发送消息?

设计说发布者需要等待并知道消费者的处理何时完成,以便在客户端执行某项任务(取决于成功/失败)。

我尝试了下面的代码但是在没有发送任何Ack或Nack的情况下立即从队列中删除了消息。我很困惑

发布商代码:

using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.QueueDeclare("test", durable, false, false, null);
                    channel.TxSelect();
                    var properties = channel.CreateBasicProperties();
                    properties.SetPersistent(true);

                    string message = "Hello World!";
                    var body = Encoding.UTF8.GetBytes(message);



                    channel.BasicPublish("", "test", properties, body);
                    channel.TxCommit();
                    Console.WriteLine(" [x] Sent {0}", message);
                }
            }

消费者代码

 using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("test", durable, false, false, null);

                var consumer = new QueueingBasicConsumer(channel);
                channel.BasicConsume("test", true, consumer);

                Console.WriteLine(" [*] Waiting for messages." +
                                         "To exit press CTRL+C");
                while (true)
                {
                    var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                }
            }
        }

注意:我意识到channel.BasicConsume("test", true, consumer);有noAck为true。我将其更改为channel.BasicConsume("test", false, consumer);

当我使用channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);时,我可以看到消息已从队列中删除但是,Publisher如何知道消费者已成功处理它?<​​/ p>

3 个答案:

答案 0 :(得分:1)

这是一个重复的问题。检查此主题,这是一个类似的问题,答案正确:Why doesn't Channel.waitForConfirmsOrDie block?

答案 1 :(得分:1)

  

如何确保发布服务器仅在消费者准备好处理时才向服务器发送消息?

你做不到。更重要的是,你不应该。使用消息传递架构的关键是忘记这类问题。检查this

此外,RabbitMQ将为您存储此消息,直到有人准备在队列持久时处理它们。

  

但是,Publisher如何知道消费者成功处理了它?

不,不会。 ack只在RabbitMQ和您的消费者之间或RabbitMQ和您的制作人之间。有关ack / nack的详细信息,请查看this

如果我能正确理解你,你想在这里实现的是一种“健谈”的架构,消费者也是出版商“响应消息”的制作者,像“嘿,我是”这样的消息完成消息XX,一切都很好“。

这样做的简单方法是将您的消费者设置为生产者,并将您的生产者设置为消费者。您只需要在消息中添加guid或某种唯一ID,当您完成它后,您将在另一个具有该id作为内容的队列上发送消息,以通知原始发布者(这是一个消费者)这个“响应”队列)工作已成功完成。

希望有所帮助:)

答案 2 :(得分:0)