MassTransit 学习记录(三) 广播 & 负载

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

这篇其实不能说是学习记录,而是实战问题以及解决记录了,负载均衡就是将一个程序发布到多台服务器上,通过路由(软/硬)来分配实际的访问指向,这是横向扩展;广播则是将消息推送给所有注册了的消费者,这是一种消息传播方式。这两者其实并没多大关系,只是因为使用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的方式

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值