RabbitMQ 入门:2. Exchange 和 Queue

上文RabbitMQ 入门:1. Message Broker(消息代理)提到过RabbitMQ实现了AMQP这个协议(RabbitMQ所支持的AMQP的版本是0.9.1),这个协议的内容很多,但为了构建入门级的分布式应用,我们只需要了解以下几点即可。

 

在最简单的场景下,RabbitMQ的架构示意图大致如下:

  • 首先某个消息从发布者那里发往    RabbitMQ

  • 这个消息需要声明一个Exchange(也可以翻译成交换机),并被发往这个    Exchange

    • Exchange      有点类似“暂存区”,消息都会发往Exchange。用个类比来说:Exchange      就像邮箱一样,我们写的信件首先都要放到邮箱里才能进行发送。

  • 然后,Exchange    将使用消息内的一些信息以及它自己的配置来决定一条或多条发送消息的路由。

  • 这些路由都通向一个Queue(队列),消息会存储在这个Queue里,等待消息的接收者来进行使用。

  • 一个消息的接收者可以使用Queue中的信息。一旦确认这个消息被传递成功,那么它将从Queue中被删除。

    • RabbitMQ      所提供的松耦合的特性,主要是因为ExchangeQueue的分离。

    • 继续使用邮箱的类比,Queue就相当于是接收信件的邮箱。而根据邮件地址,邮件系统会选择不同的邮箱来接收邮件。

 

而由于RabbitMQ处理的是消息,而不是信件,所以它的选项会更多:RabbitMQ一共有4Exchange

  • Direct Exchange。它是默认的Exchange。它会把消息发送到一个接收者。如果注册了多个接收者来监听同样的路由Key,那么    RabbitMQ将会向每个Queue轮流发送一条消息,相当于提供了一个简单的负载均衡

  • Fanout Exchange它把消息的副本发送到每个绑定到该    ExchangeQueue上面。而这里的Queue没有办法对消息进行过滤,如果需要过滤,则需要在消息接收者那里实现。

  • Topic Exchange。它和Direct Exchange类似,但不同的是:每个消息接收者监听特定的路由Key,它们会收到消息的副本。

    • 例如聊天室就可以使用Topic      Exchange。每个聊天室的ID可以作为路由Key,这样就可以保证消息只会发送给同一个聊天室的其他参与者。

  • Headers Exchange。这类    Exchange会忽略路由Key,取而代之的是,它们会查看消息的Header,并由此来决定消息应该发往哪个QueueQueue可以有一个或多个Header用来进行匹配。这也就开启了复杂的路由场景,例如某个Queue有时可以接收到某类消息而有时则不行。

 

下面仅针对Fanout Exchange进行进一步说明:

 

Fanout Exchange

当消息被发往RabbitMQ的时候,需要指明它需要发送到哪个Exchange。而这个Exchange就可以被设置成为所谓的Fanout Exchange

使用Fanout Exchange,消息会被克隆,并被发送到所有与这个Exchange绑定的Queue上,如下图:

这里每一个Queue都会得到属于自己的消息的副本,这些消息副本就i可以被消息的接收者所使用。

在很多大规模多人游戏的场景中,经常使用这种方式来同步玩家的数据:每个玩家都订阅到一个Fanout Exchange,你游戏的实例只需要将数据发送到一个地方即可,游戏中其他的玩家就会获得更新,而你的游戏实例就不需要知道如何数据发往每一个玩家了。