基于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 转发消息是最快的。

     /// <summary>

/// 生产者

/// </summary>

/// <param name="change"></param>

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<MyMessage>(msg));

}

else

{

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

}

}

/// <summary>

/// 消费者

/// </summary>

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<MyMessage>((message, info) => { Console.WriteLine("Body: {0}", message.Body); });

});

}

适用场景:

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

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

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

二. Direct Exchange

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

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

/// <summary>

/// 生产者

/// </summary>

/// <param name="change"></param>

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<MyMessage>(msg));

}

else

{

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

}

}

/// <summary>

/// 消费者

/// </summary>

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<MyMessage>((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 使用非常灵活。

     /// <summary>

/// 生产者

/// </summary>

/// <param name="change"></param>

private static void ProducerMessage(MyMessage msg)

{

//// 创建消息bus

IBus bus = CreateBus();

try

{

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

}

catch (EasyNetQException ex)

{

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

}

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

}

/// <summary>

/// 消费者

/// </summary>

private static void ConsumeMessage(MyMessage msg)

{

//// 创建消息bus

IBus bus = CreateBus();

try

{

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

}

catch (EasyNetQException ex)

{

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

}

}

使用场景:

新闻的分类更新

同意任务多个工作者协调完成

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

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

以上这篇基于RabbitMQ几种Exchange 模式详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 基于RabbitMQ几种Exchange 模式详解 的全部内容, 来源链接: utcz.com/p/215440.html

回到顶部