想咨询下RabbitMQ 能不能配置成广播模式。
我有一个消息发送程序,两个消息处理程序。但是我希望这两个消息处理程序能够获取到发送程序发送的所有消息。而不是把消息分发到两个处理程序中。
A:发送消息
B、C:消息处理
A发送了10条消息,希望B、C都能获取到10条消息,而不是B获取5条C获取5条。请问这个应该如何配置。
我尝试了将RabbitMQ.NET 的Exchange 设置成为了不同类型,但是结果依然都是只能分发。
你将BC写在一个程序里不就好了..
目前的需求就是需要分别在B和C里面处理,如果是合起来处理。我也就没必要问这个问题了。
你用两个队列不就搞定了
不行,满足不了我的需求。
@yzy: 为什么这么说
你exchange设为fanout,把相关队列加到exchange的目标中来就能广播到这些队列了啊
这个方式我也尝试过。好像还是不行,还是进行了分发。难道是我的代码编写有问题。你有没有做过这方面的代码,给出来参考参考。
@yzy: 你贴下你的代码,贴下你exchange的设置和其对q的绑定的图。
@Daniel Cai:
发送:
var connection = CreateConnection(); var channel = connection.CreateModel(); //声明转发器和类型 channel.ExchangeDeclare(ExchangeName, "fanout" ); string s = DateTime.Now.ToLongTimeString()+" : log something"; //往转发器上发送消息 var props = channel.CreateBasicProperties(); props.DeliveryMode = 2; var msgBody = Encoding.UTF8.GetBytes(s); channel.BasicPublish(ExchangeName, "",null, body: msgBody); channel.Dispose(); connection.Dispose();
接收
using (var connection = CreateConnection()) { using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(ExchangeName, "fanout"); // 创建一个非持久的、唯一的且自动删除的队列 String queueName = channel.QueueDeclare().QueueName; // 为转发器指定队列,设置binding channel.QueueBind(queueName, ExchangeName, ""); QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel); // 指定接收者,第二个参数为自动应答,无需手动应答 channel.BasicConsume(queueName, true, consumer); while (true) { var delivery = consumer.Queue.Dequeue(); String message = ( Encoding.UTF8.GetString(delivery.Body)); method(message); } } }
@yzy: 你这些declare信息,binding信息都可以直接在rabbitmq上做,没必要在代码中做,你只需要把exchange和q设为durable(和数据持久化无关,只是保证在mq重启后队列和exchange相关信息不会丢失,需要集群中至少有一个rabbitmq是基于磁盘的)。
channel.QueueBind(queueName, ExchangeName, "");
这个你有多少个q绑定到这个exhcnage上来了?
@Daniel Cai: 目前2个。
@yzy: String queueName = channel.QueueDeclare().QueueName;
你这句应该来说只有一个q,应该使用QueueDeclare另外一个重载方法显式指定多个q,并在把exchange绑定到这些q上。
你上下mq的web控制台看下你申明的q是不是你所期望的。如果在对应exchange下看到其binding指向了多个q,并且没有路由key就可以实现针对这些q的广播了。
@Daniel Cai: 我是两个window 程序执行的。 发送端一个程序。消息处理端是两个程序,所以是两个q。
@yzy: 我明白你的意思,我前面说的意思是这行代码
String queueName = channel.QueueDeclare().QueueName;
有问题(根据方法描述,这个方法是由mq自动给你分配一个随机的q),所以需要你直接去rabbitmq的管理界面看下这个exchange下到底有几个binding的q,你的concumser是不是都落在一个q上了。
之前我这边的做法都是直接在mq上建好这些东西,代码上就不用再申明这些玩意和他们之间的联系了,所以不清楚你这种代码写的方式是否有问题
@Daniel Cai: 已经ok 了,谢谢了。