我正在尝试获得RabbitMQ设置,在这里我可以选择将消息发布为服务,以扇出或直接发布。但是,当我发布到扇出交换时,我看到了传递给所有服务的消息,而且还以循环方式传递。因此,其中一项服务总是两次看到相同的消息。
这是完整的副本:
using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
namespace rabbitmq_exchanges_repro
{
class Program
{
static void Main(string[] args)
{
var hostName = "localhost";
var factory = new ConnectionFactory
{
AutomaticRecoveryEnabled = true,
HostName = hostName,
};
var connection = factory.CreateConnection();
var model = connection.CreateModel();
var serviceName = "service1";
// This queue is for round-robin messages distributed to instances of the service with the specified service name.
var directExchangeName = $"{serviceName}-direct";
model.QueueDeclare(
serviceName,
durable: true,
exclusive: false,
autoDelete: false);
model.ExchangeDeclare(
exchange: directExchangeName,
type: "direct",
durable: true,
autoDelete: false);
model.QueueBind(
queue: serviceName,
exchange: directExchangeName,
routingKey: string.Empty);
// This is for fanout messages distributed to all services with the specified service name.
var fanoutExchangeName = $"{serviceName}-fanout";
model.ExchangeDeclare(
exchange: fanoutExchangeName,
type: "fanout",
durable: true,
autoDelete: false);
var fanoutQueueName = model
.QueueDeclare()
.QueueName;
model.QueueBind(
queue: fanoutQueueName,
exchange: fanoutExchangeName,
routingKey: string.Empty);
var directConsumer = new EventingBasicConsumer(model);
var fanoutConsumer = new EventingBasicConsumer(model);
var workItemConsumerTag = model.BasicConsume(
queue: serviceName,
autoAck: true,
consumer: directConsumer);
var fanoutConsumerTag = model.BasicConsume(
queue: fanoutQueueName,
autoAck: true,
consumer: fanoutConsumer);
directConsumer.Received += (o, e) =>
{
Console.WriteLine("Received message (direct)");
};
fanoutConsumer.Received += (o, e) =>
{
Console.WriteLine("Received message (fanout)");
};
Console.WriteLine("[P]ublish");
Console.WriteLine("E[x]it");
var exit = false;
while (!exit)
{
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.P:
model
.BasicPublish(
exchange: fanoutExchangeName,
routingKey: string.Empty,
body: new byte[] { 1, 2, 3 });
break;
case ConsoleKey.X:
exit = true;
break;
}
}
model.BasicCancel(workItemConsumerTag);
model.BasicCancel(fanoutConsumerTag);
model.Close();
model.Dispose();
connection.Close();
connection.Dispose();
}
}
}
在两个单独的控制台窗口中运行以上代码。如果在一个窗口中按P
,您会看到一个实例输出了我期望的值:
Received message (fanout)
但是另一个窗口输出:
Received message (fanout)
Received message (direct)
尽管事实是PublishBasic
调用指定了扇出交换名称。这里发生了什么?如何确保在这种情况下不涉及直接交换?
答案 0 :(得分:1)
我无法使用RabbitMQ 3.7.14和您的代码进行复制。我只在每个终端窗口中收到“收到的消息(扇出)”消息。也许RabbitMQ中有旧的绑定?您应该重置实例并重试。
注意: RabbitMQ团队监视rabbitmq-users
mailing list,并且有时仅在StackOverflow上回答问题。