基于RabbitMQ几种Exchange 模式详解

网友投稿 376 2023-03-19


基于RabbitMQ几种Exchange 模式详解

AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列。生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。先由Exchange来接收,然后Exchange按照特定的策略转发到Queue进行存储。同理,消费者也是如此。Exchange 就类似于一个交换机,转发各个消息分发到相应的队列中。

RabbitMQ提供了四种Exchange模式:fanout,direct,topic,header 。 header模式在实际使用中较少,本文只对前三种模式进行比较。

一. Fanout Exchange

所有发送到Fanout Exchange的消息都会被转发到与该Exchange 绑定(Binding)的所有Queue上。

Fanout Exchange 不需要处理RouteKey 。只需要简单的将队列绑定到exchange 上。这样发送到exchange的消息都会被转发到与该交换机绑定的所有队列上。类似子网广播,每台子网内的主机都获得了一份复制的消息。

所以,Fanout Exchange 转发消息是最快的。

///

/// 生产者

///

///

private static void ProducerMessage(MyMessage msg)

{

var advancedBus = CreateAdvancedBus();

if (advancedBus.IsConnected)

{

var exchange = advancedBus.ExchangeDeclare("user", ExchangeType.Fanout);

advancedBus.Publish(exchange, "", false, new Message(msg));

}

else

{

Console.WriteLine("Can't connect")xxEEI;

}

}

///

/// 消费者

///

private static void ConsumeMessage()

{

var advancedBus = CreateAdvancedBus();

var exchange = advancedBus.ExchangeDeclare("user", ExchangeType.Fanout);

var queue = advancedBus.QueueDeclare("user.notice.wangwu");

advancedBus.Bind(exchange, queue, "user.notice.wangwu");

advancedBus.Consume(queue, registration =>

{

registration.Add((message, info) => { Console.WriteLine("Body: {0}", message.Body); });

});

}

适用场景:

第一:大型玩家在玩在线游戏的时候,可以用它来广播重大消息。这让我想到电影微微一笑很倾城中,有款游戏需要在世界上公布玩家重大消息,也许这个就是用的MQ实现的。这让我不禁佩服肖奈,人家在大学的时候就知道RabbitMQ的这种特性了。

第二:体育新闻实时更新到手机客户端。

第三:群聊功能,广播消息给当前群聊中的所有人。

二. Direct Exchange

所有发送到Direct Exchange的消息被转发到RouteKey中指定的Queue。

Direct模式,可以使用rabbitMQ自带的ExxxEEIchange:default Exchange 。所以不需要将Exchange进行任何绑定(binding)操作 。消息传递时,RouteKey必须完全匹配,才会被队列接收,否则该消息会被抛弃。

///

/// 生产者

///

///

private static void ProducerMessage(MyMessage msg)

{

var advancedBus = CreateAdvancedBus();

if (advancedBus.IsConnected)

{

var queue = advancedBus.QueueDeclare("user.notice.zhangsan");

advancedBus.Publish(Exchange.GetDefault(), queue.Name, false, new Message(msg));

}

else

{

Console.WriteLine("Can't connect");

}

}

///

/// 消费者

///

private static void ConsumeMessage()

{

var advancedBus = CreateAdvancedBus();

var exchange = advancedBus.ExchangeDeclare("user", ExchangeType.Direct);

var queue = advancedBus.QueueDeclare("user.notice.lisi");

advancedBus.Bind(exchange, queue, "user.notice.lisi");

advancedBus.Consume(queue, registration =>

{

registration.Add((message, info) =>

{

Console.WriteLine("Body: {0}", message.Body);

});

});

}

三. Topic Exchange

所有发送到Topic Exchange的消息被转发到所有关心RouteKey中指定Topic的Queue上,

Exchange 将RouteKey 和某Topic 进行模糊匹配。此时队列需要绑定一个Topic。可以使用通配符进行模糊匹配,符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“log.#”能够匹配到“log.info.oa”,但是“log.*” 只会匹配到“log.error”。

所以,Topic Exchange 使用非常灵活。

///

/// 生产者

///

///

private static void ProducerMessage(MyMessage msg)

{

//// 创建消息bus

IBus bus = CreateBus();

try

{

bus.Publish(msg, x => x.WithTopic(msg.MessageRouter));

}

catch (EasyNetQExcehttp://ption ex)

{

//处理连接消息服务器异常

}

bus.Dispose();//与数据库connection类似,使用后记得销毁bus对象

}

///

/// 消费者

///

private static void ConsumeMessage(MyMessage msg)

{

//// 创建消息bus

IBus bus = CreateBus();

try

{

bus.Subscribe(msg.MessageRouter, message => Console.WriteLine(msg.MessageBody), x => x.WithTopic("user.notice.#"));

}

catch (EasyNetQException ex)

{

//处理连接消息服务器异常

}

}

使用场景:

新闻的分类更新

同一问题需要特定人员知晓

Topic Exchange的使用场景很多,我们公司就在使用这种模式,将足球事件信息发布,需要使用这些事件消息的人只需要绑定对应的Exchange就可以获取最新消息。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:用Webpack构建Vue项目的实践
下一篇:Spring Cloud出现Options Forbidden 403问题解决方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~