繁体   English   中英

每隔x个间隔以y批处理大小C#消耗/读取消息来自Rabbit MQ

[英]C# Consuming / Reading message every x interval with y batch size From Rabbit MQ

我使用Rabbit MQ按顺序处理消息。 现在,我有一个场景,不需要立即使用消息,但是我想每1(x)分钟使用/读取MQ的消息,批处理大小为20(y)

因此,我可以一次性处理这20条消息,并通过一次调用将其保存到数据库,而不是为每条消息调用20次。

因此,如何在每个x间隔内批量接收/使用消息。

我已经看到以下信息, 批量 使用消息-RabbitMQRabbitmq使用.NET使用单个同步调用检索多条消息

我尝试实现第二个问题的实现(questions / 32309155),但无法正常工作,不理解“ consumer.Received”将收到** _ fetchSize ==> 20 **的意思,它将以单次读取方式接收20条消息? 或它将如何工作,因为我将fetchsize更改为10,但是Consumer.received正在接收单个消息。

using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.BasicQos(0, 1, false);
                channel.ExchangeDeclare("helloExchange", type:"direct");
                channel.QueueDeclare(queue: "hello", durable: true, exclusive: false, autoDelete: false,
                    arguments: null);

                channel.QueueBind("hello", "helloExchange", routingKey:"hello");

                var consumer = new EventingBasicConsumer(channel);

                consumer.Received += (model, ea) =>
                {
                    bool canAck = false;
                    var retryCount = 0;



                    try
                    {
                        var body = ea.Body;
                        var message = Encoding.UTF8.GetString(body);
                       // DO PROCESS MESSAGE HERE
                        Console.WriteLine($"{typeof(MyConsumer).Name} Message consumed {message}");
                        canAck = true;
                    }
                    catch (Exception ex)
                    {canAck = false;
                      // LOG ERROR
                    }

                    try
                    {
                        if (canAck)
                        {
                            channel.BasicAck(ea.DeliveryTag, false);
                        }
                        else
                        {
                            channel.BasicNack(ea.DeliveryTag, false, false);
                        }
                    }
                    catch (AlreadyClosedException ex)
                    {
                        Console.WriteLine(ex.Message + " >> RabbitMQ is closed!");
                    }
                };
                channel.BasicConsume(queue: "hello", autoAck: false, consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }

使用者一次只会收到一条消息。 提取大小将确定可以在通道上向消费者传递多少未确认的消息。

因此,假设抓取大小为3,例如,将传递3条消息,但是如果您不确认任何消息,则意味着即使队列中收到新消息(第4条),也不会将其发送到通道(因此直到您确认3条初始消息中的至少一条。

为了能够处理您的情况并批量使用消息,您可以执行以下操作:

  • 将fetchSize设置为20
  • 每当您收到新消息时,都会将其保存到列表中
  • 一旦达到限制(20),您就开始处理它并确认批处理中的所有消息(从而清除列表)
  • 批处理完成并确认所有消息后,您将开始接收新消息(然后重新开始该流程)

即使从技术上讲这是可行的,我也不会进行此实现,因为它将使重试/错误处理等操作变得更加复杂。使用消息队列,您可以选择使代码具有原子性,幂等性和弹性,这将导致更容易的错误/重试处理。

暂无
暂无

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

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