这篇其实不能说是学习记录,而是实战问题以及解决记录了,负载均衡就是将一个程序发布到多台服务器上,通过路由(软/硬)来分配实际的访问指向,这是横向扩展;广播则是将消息推送给所有注册了的消费者,这是一种消息传播方式。这两者其实并没多大关系,只是因为使用MassTransit,那就避免不了会遇到这两个问题,而这两个问题在MQ中又紧密关联,所以一起在这里进行说明。
首先是基础部分,我们先看下RabbitMQ的Publish/Subscribe,相关官方网址为 http://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html,按照其例子,我们可以很顺利的测试出消息的确成功的广播给了多个消费者,这时候我们稍微修改下程序例子代码,不用多,就只要改下接收端的声明QueueName的那一行代码
//var queueName = channel.QueueDeclare().QueueName;
var queueName = channel.QueueDeclare("mt_fanout", false, false, true, null).QueueName;
PS:在RabbitMQ中,Exchange的durable与Queue的durable没有直接关系,两者可以设置为不一致
这时你再打开多个接收端程序,并通过发送端进行广播测试,你会发现实际只有一个接收端能收到消息了,Why?问题根源在于RabbitMQ的Work Queues,相关官方网址为 http://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html,当指定QueueName时,即多个消费者都指向同一个Queue,那么在这些消费者中,有且只有一个消费者能收到消息,这也就是负载均衡的保证;而通过channel.QueueDeclare().QueueName得到的QueueName是由程序帮你生成的一个随机Name(不知道会不会重复),这样多个接收客户端就会产生多个接收队列,每个队列仅供自己的消费者消费,这样才是广播。
我们已经了解了在RabbitMQ下怎么实现广播,现在我们可以来试验怎么在MassTransit中实现广播和负载了
其实发送端没变化,还是采用Publish即可,如果要用Send方法其实也可以,GetSendEndpoint方法中传入的Uri还是mq的地址即可,但个人不推荐这么做,下面是代码,这里直接用第一篇文章中的发送代码做例子
rbBus.Publish<IMessageContract>(new { Value = text });//通过Publish推送
var point = rbBus.GetSendEndpoint(new Uri("rabbitmq://192.168.5.136/")).Result;
point.Send<IMessageContract>(new MessageContract { Value = $"Send To handler { text}" });//通过Send发送然后接收端例子也只是稍作改动,代码如下
//configure.ReceiveEndpoint(host, e =>
//{
// //e.AutoDelete = false;
// //e.Durable = true;
// //e.ExchangeType = "fanout";
// e.Consumer(() => new AnotherMessageContractConsumer());
//});
configure.ReceiveEndpoint(host, "mt_fanout_0", e =>
{
e.Consumer(() => new AnotherMessageContractConsumer());
});
configure.ReceiveEndpoint(host, "mt_fanout_1", e =>
{
e.Consumer(() => new AnotherMessageContractConsumer());
});一种方法就是上面注销部分的不指定QueueName,由MQ自动帮你生成,另一种就是下面的方法,分别指定不同的QueueName,如果不需要负载的话,那么你可以采取第一种自动生成的方式,如果需要负载的话,那么请采用指定不同QueueName的方式

本文解析了如何在RabbitMQ中实现消息广播与负载均衡,重点介绍了通过指定队列名称来控制消息传递的方式,以及如何在MassTransit中应用这些概念。

被折叠的 条评论
为什么被折叠?



