繁体   English   中英

RabbitMQ - 了解消费者已启动

[英]RabbitMQ - Knowing Consumer is up

我有一些关于在 RabbitMQ 中编码的问题......我对这个世界并不陌生,并且根据提供给我的用于实现的设计提出了问题......

  • 如果我从消费者发送 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); 对 true 没有确认。 我把它改成了channel.BasicConsume("test", false, consumer);

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

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

你不能。 更重要的是,你不应该。 使用消息传递架构的重点是忘记这类问题。 检查这个

此外,RabbitMQ 将为您存储这些消息,直到有人准备好处理它们(如果队列是持久的)。

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

不,不会。 ack 仅在 RabbitMQ 和您的消费者之间或 RabbitMQ 和您的生产者之间。 检查以获取有关 ack/nack 的一些详细信息。

如果我能正确理解你的话,你想在这里实现的是一种“健谈”架构,其中消费者也是发布者“响应消息”的生产者,诸如“嘿,我完成了消息”之类的消息XX,一切都好”。

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

希望它有帮助:)

这是一个重复的问题。 检查此线程,这是一个具有正确答案的类似问题: Why does Channel.waitForConfirmsOrDie block?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM