RabbitMQ:同一个线程上的多个频道导致重复的消息?

时间:2015-10-06 07:34:15

标签: c# rabbitmq

我一直在使用.NET客户端测试RabbitMQ 3.5.5,并且看到了一些我不理解的行为。具体来说,我有一个生产者,它使用特定的路由密钥将10,000条消息写入exchange。有一个队列映射到具有相同路由密钥的交换。

如果我然后创建两个频道(IModel),每个频道都有一个EventingBasicConsumer并告诉他们从direct交换机上的同一队列中消费,我似乎得到了超过10,000条消息。

鉴于交换是一个direct交换,我本来期望在消费者中进行轮询。我注意到如果我在单独的线程中创建使用者,那么我就不会看到这种行为。

以下示例代码:

    static void Main(string[] args)
    {
        //set up the exchange and queue
        string exchangeName = "testexchange";
        string queueName = "testqueue";

        ConnectionFactory connectionFactory = new ConnectionFactory() { HostName = "localhost" };
        IConnection connection = connectionFactory.CreateConnection();

        IModel producerChannel = connection.CreateModel();
        producerChannel.ExchangeDeclare(exchangeName, "direct", false);

        //consumer 1
        IModel consumerChannel1 = connection.CreateModel();
        consumerChannel1.QueueDeclare(queueName, false, false, false, null);
        consumerChannel1.QueueBind(queueName, exchangeName, string.Empty);

        //consumer 2
        IModel consumerChannel2 = connection.CreateModel();
        consumerChannel2.QueueDeclare(queueName, false, false, false, null);
        consumerChannel2.QueueBind(queueName, exchangeName, string.Empty);

        int publishCount = 10000;
        int receivedCount = 0;

        //publish to the exchange
        for (int i = 0; i < publishCount; i++)
            producerChannel.BasicPublish(exchangeName, string.Empty, null, Encoding.UTF8.GetBytes(i.ToString()));

        //set up the consumers to consume
        EventingBasicConsumer consumer1 = new EventingBasicConsumer(consumerChannel1);
        consumer1.Received += (sender, eventArgs) =>
        {
            Interlocked.Increment(ref receivedCount);
        };
        consumerChannel1.BasicConsume(queueName, true, consumer1);

        EventingBasicConsumer consumer2 = new EventingBasicConsumer(consumerChannel2);
        consumer1.Received += (sender, eventArgs) =>
        {
            Interlocked.Increment(ref receivedCount);
        };
        consumerChannel2.BasicConsume(queueName, true, consumer2);

        //wait a bit
        DateTime waitStart = DateTime.UtcNow;
        while (DateTime.UtcNow.Subtract(waitStart).TotalSeconds < 10 && receivedCount < publishCount)
            Thread.Sleep(100);


        Console.WriteLine("Total received: {0}", receivedCount); //usually has a number more than 10,000
        Console.ReadLine();

        producerChannel.ExchangeDelete(exchangeName);
        consumerChannel1.QueueDelete(queueName);

        producerChannel.Dispose();
        consumerChannel1.Dispose();
        consumerChannel2.Dispose();

       connection.Dispose();
    }

0 个答案:

没有答案