一、AMQP基本组成及基本概念

1.组成

  AMQP的基本组成如下图所示,该模型同样适用于rabbitmq。

springcloud rabbitmq交换机类型_消息路由


  基于下图消息的流向:生产者(publisher/producer)生产具有指定路由键(routing key)的消息将其发布给消息代理(broker 即rabbitmq)中的交换机(exchange),交换机将消息中的路由键与队列(queue)绑定信息(binding)中存储的路由键对比,将消息路由到匹配的队列中。队列再将信息通过连接(connection)中的通道(channel)推送给订阅了消息的消费者(consumer)。

2.基本概念

  a.生产者(Publisher/Producer):生产者顾名思义就是生产消息的角色。生产者会将消息发送给交换机。为了使交换机正确的将消息路由给队列,发布消息时需指定消息的路由键(routing key)。

b.消息代理(Broker):代理的职能就是接收发布者发布的消息并将消息推送给订阅了消息的消费者。rabbitmq就相当于一个代理。

c.虚拟主机(Virtual Host):出于多租户和安全因素设计的,把AMQP的基本组(交换机,队列,绑定称为AMQP组件)件划分到一个虚拟的分组中,类似于网络中的namespace概念。当多个不同的用户使用同一个borker(RabbitMQ server)提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue等。

d.交换机(Exchange):交换机负责接收消息并按照一定的规则将消息路由给队列。路由的规则存储在交换机与队列绑定时指定的routing key。

e.绑定(Binding):交换机和队列之间通过路由键(routing key)相互绑定起来,并根据路由键将消息路由到对应队列。

f.队列(Queue):消息的载体,exchange中的消息将被路由到队列中,并推送给消费者或者被消费者取走。

g.连接(Connection):消费者和生产者与消息代理之间的连接

h.通道(Channel):如果消费者每一次从代理中取消息都建立一次连接的话,在消息量大的情况下建立多个连接将会有巨大的开销。Channel是在Connection内部建立的逻辑连接。如果应用程序支持多线程,可以为每个线程建立单独的通道进行通讯。AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。

i.消费者(Consumer):接收消息的角色就是消费者

二、交换机
1.交换机的分类
  交换机主要分为四种,还有一种比较特殊的默认交换机:

a.直连交换机(direct exchange):将交换机和一个队列绑定起来,并给该绑定一个路由键。当携带路由键的消息发送给交换机时,交换机会寻找具有匹配的路由键的绑定,并将消息路由给对应的队列。该种交换机为直连交换 机。直连交换机经常用来循环分发任务给多个消费者,此时消息的负载均衡是发生在消费者之间的。

对于下图而言:当携带有orange路由键的消息被发送到交换机时,消息会被路由到队列Q1。

springcloud rabbitmq交换机类型_消息路由_02


  b.主题交换机(topic exchange):将交换机和队列绑定起来,并给绑定赋予一个模式路由键。当携带路由键的消息发送给交换机时,交换机会寻找具有匹配的模式路由键的绑定,并将消息路由给对应的队列。该种交换机为主题交换机。主题交换机经常用来实现各种分发、订阅模式及其变种。主题交换机通常用来实现消息的多播路由(multicast routing)。

  

  模式路由键routing key一般使用 . 来分隔单词,而且有两个通配符可以使用。* 代表任意一个单词,#代表0个或多个单词。例如:apple.orange.penaunt,.orange.,orange.#。

主题交换机拥有非常广泛的用户案例。无论何时,当一个问题涉及到那些想要有针对性的选择需要接收消息的 多消费者/多应用(multiple consumers/applications) 的时候,主题交换机都可以被列入考虑范围。
  使用案例:

分发有关于特定地理位置的数据,例如销售点

由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务

股票价格更新(以及其他类型的金融数据更新)

涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)

云端的不同种类服务的协调

分布式架构/基于系统的软件封装,其中每个构建者仅能处理一个特定的架构或者系统。

  对于下图而言:当携带routing key为apple.orange.penanut的消息被发送给交换机时,将会被路由到队列Q1中。当lazy.apple.pen被发送到交换机时,将会被路由到队列Q2中。

springcloud rabbitmq交换机类型_消息路由_03


  c.扇形交换机/广播交换机(fanout exchange):将交换机和任意多个队列绑定起来,不管绑定上的路由键,当消息被发送到交换机上时,消息将会被拷贝并路由到所有绑定到该交换机上的队列中。

  对下图而言:携带任何routing key的消息被发送到交换机上时,消息都将被拷贝并分发到Q1,Q2,Q3中。

springcloud rabbitmq交换机类型_属性值_04


  扇形交换机的使用的案例:

大规模多用户在线(MMO)游戏可以使用它来处理排行榜更新等全局事件

体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端

分发系统使用它来广播各种状态和配置更新

在群聊的时候,它被用来分发消息给参与群聊的用户。(AMQP没有内置presence的概念,因此XMPP可能会是个更好的选择)

  d.头交换机(header exchange):有时消息的路由操作会涉及到多个属性,此时使用消息头就比用路由键更容易表达,头交换机(headers exchange)就是为此而生的。头交换机使用多个消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则。

我们可以绑定一个队列到头交换机上,并给他们之间的绑定使用多个用于匹配的头(header)。消息代理得从应用开发者那儿取到更多一段信息,换句话说,它需要考虑某条 消息(message)是需要部分匹配还是全部匹配。上边说的“更多一段消息”就是"x-match"参数。当"x-match"设置为“any”时,消息头的任意一个值被匹配就可以满足条件,而当"x-match"设置为“all”的时候,就需要消息头的所有值都匹配成功。

头交换机可以视为直连交换机的另一种表现形式。头交换机能够像直连交换机一样工作,不同之处在于头交换机的路由规则是建立在头属性值之上,而不是路由键。路由键必须是一个字符串,而头属性值则没有这个约束,它们甚至可以是整数或者哈希值(字典)等。头交换机用的比较少,了解一下概念即可。

当携带有{“orange”:“apple”}header参数的消息被发送到交换机时,消息将被路由到Q1队列中。

springcloud rabbitmq交换机类型_rabbitmq_05


  e.默认交换机(default exchange):默认交换机是一种特殊的直连交换机(direct exchange)。它是由消息代理默认声明的,该交换机有一个特性,所有新建的队列都会默认绑定到默认交换机上,并且绑定的routing ke就是队列的名字。

以上摘抄