批量消费 - RabbitMQ

时间:2016-08-09 07:28:37

标签: c# rabbitmq message-queue

我能够使用上述代码使用多个生产者使用不同路由密钥发送到同一交换的多条消息,并能够将每条消息插入数据库。

但是这会消耗太多资源,因为消息会一个接一个地插入到数据库中。所以我决定去批量插入,我发现我可以设置BasicQos

在BasicQos中将消息限制设置为10之后,我的期望是Console.WriteLine必须写入10条消息,但它不是预期的。

我的期望是从队列中消耗N个号码消息并进行批量插入并成功发送ACK否则无ACK

以下是我使用的代码段。

using (var connection = factory.CreateConnection())
{
    using (var channel = connection.CreateModel())
    {
        channel.QueueBind(queue: "queueName", exchange: "exchangeName", routingKey: "Producer_A");
        channel.QueueBind(queue: "queueName", exchange: "exchangeName", routingKey: "Producer_B");

        channel.BasicQos(0, 10, false);

        var consumer = new EventingBasicConsumer(channel);
        channel.BasicConsume(queue: "queueName", noAck: false, consumer: consumer);

        consumer.Received += (model, ea) =>
        {
            try
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);

                // Insert into Database

                channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                Console.WriteLine(" Recevier Ack  " + ea.DeliveryTag);
            }
            catch (Exception e)
            {
                channel.BasicNack(deliveryTag: ea.DeliveryTag, multiple: false, requeue: true);
                Console.WriteLine(" Recevier No Ack  " + ea.DeliveryTag);
            }
        };

        Console.ReadLine();
    }
}

1 个答案:

答案 0 :(得分:4)

BasicQos = 10表示客户端一次只能获取10条消息,但是当您使用它时,您将始终看到一条消息。 请在此处阅读:https://www.rabbitmq.com/consumer-prefetch.html

  

AMQP指定允许您限制数量的basic.qos方法   消费时信道(或连接)上未确认的消息   (又名"预取计数")。

对于您的范围,您必须下载消息,将其放在临时列表中,然后插入到数据库中。

然后你可以使用:

channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: true);
  

void basicAck()

     

参数:   deliveryTag - 收到的标签   AMQP.Basic.GetOk或AMQP.Basic.Deliver

     

倍数 - 确认无误   所有消息,包括提供的交付标签;假的   只承认提供的交货标签。

示例

final List<String> myMessagges = new ArrayList<String>();
        channel.basicConsume("my_queue", false, new DefaultConsumer(channel) {

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                myMessagges.add(new String(body));
                System.out.println("Received...");

                if (myMessagges.size() >= 10) {
                    System.out.println("insert into DB...");
                    channel.basicAck(envelope.getDeliveryTag(), true);
                    myMessagges.clear();
                }


            }
        });