簡體   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