AMQP 0-9-1(Advanced Message Queuing Protocol)高级消息队列协议是一个消息协议,它支持符合标准的客户端请求程序与符合标准的消息中间件代理进行通信。

概述

amqp_01.jpg

除了消息的生产者和消费者之外的Queues, Exchanges, Bindings三者被统称为AMQP的实体。也就是说AMQP主要由这三部分内容组成。下面分别介绍这三个内容。

Exchange

exchanges是AMQP中用来接收消息的实体。它接收消息,并会将消息发送到对应的queues上(这个过程也被称为路由),而其使用的路由算法则取决于Exchange的类型和指定的规则(也就是上述的Bindings)来决定。

Exchange包含了很多属性,其中比较重要的是:

Namedescription
NameExchange的名称
Durability当broker重启的时候,该Exchange是否保留(持久化)
Auto-delete当最后一个队列解绑定时删除该Exchange
Arguments可选,被插件和一些broker的特定功能所使用
Exchange typeExchange的类型,目前有direct, fanout, topic, headers四种

其中,对Exchange type各类型的描述如下:

Direct Exchange

根据routing key直接路由消息,当消息中的routing key和Queue绑定Exchange时指定的routing key(又称binding key,下文中用binding key代替)相同(完全匹配),消息就会被Exchange发往该Queue。一般用于单播路由。

direct_exchange_01.png

如上图所示,如果消息中的routing key为orange,则消息被发往Q1,如果为black或green,则被发往Q2。

但如果有多个Queue绑定的routing key相同,则这些Queue都会收到消息,类似多播。

direct_exchange_02.png

Fanout Exchange

类似于广播消息,该Exchange会把消息发到所有绑定到它的Queue上,忽略routing key。这种类型的Exchange是广播路由的理想选择。

Topic Exchange

Topic Exchange的routing key和direct类型的有所不同,不再是任意指定,必须是由点分隔的单词列表。 单词可以是任何内容,但通常它们指定与消息相关的一些功能。单词列表中可以包含任意数量的单词,最多可达255个字节。

一个发往Topic Exchange的消息的routing key应该是下面这样的:

  • "china.beijing"
  • "china.beijing.street"
  • "china.beijing.house"
  • "china.beijing.house.door"
  • "black.animal.rabbit"

在Topic Exchange中路由消息的过程类似于正则匹配,binding key就相当于一个正则表达式。Topic Exchange根据Queue对应的binding key来筛选收到的消息并发往匹配的Queue。

和正常的路由过程一样,binding key可以和routing key相同,比如某个Queue的binding key为china.beijing,那么带有routing key为china.beijing的消息就会被路由到对应的Queue。除此以外,binding key还可以有两个特殊的字符:

  • * (星号),可以替代一个单词
  • # (井号),可以替代0个或多个单词

例如,如果一个Queue的binding key为china.*,那么带china.beijing的消息就会发送给这个Queue,如果一个Queue的binding key为china.beijing.#,那么带china.beijingchina.beijing.streetchina.beijing.housechina.beijing.house.door的消息都会被发送个这个Queue。

Topic Exchange

Topic Exchange的功能十分强大,它可以表现得和其他exchange一样:

当binding key为#时,对应的Queue能接受所有的消息,相当于无视消息的routing key,如同Fanout Exchange。

当binding key都不含*#时,就如同Direct Exchange。

Headers Exchange

上述三个Exchange都是通过routing key这一个属性来路由的,而Headers Exchange则是通过多个属性进行路由,这些属性保存在消息的headers中,routing key则会被忽略。

由于有多条可匹配的属性,在路由的时候就有多种选择,有一个叫x-match的参数:

  • x-match为any时,匹配到一个属性即可
  • x-match为all时,需要匹配所有的属性才行。

Queue

AMQP中用来保存消息的实体,Exchange会将消息分发到符合要求的Queue中,Consumer 可以接收Queue里面的消息 (分为主动、被动两种,后面介绍)。

Queue使用前必须先申明(declare)。申明时,如果不存在,则会自动创建。如果已经存在且属性与申明的不一致,则会报错。生产者和消费者都需要申明对应的Queue。

Queue和Exchange共用一部分属性,但Queue也有自己独有的属性:

NameDescription
NameQueue的名称,每个Queue都必须有自己唯一的名称
Durable在broker重启后,Queue是否保留(持久化)
ExclusiveQueue只能被一个Connection使用,且当该Connection关闭时删除该Queue
Auto-delete当最后一个Consumer断开连接,则删除Queue
Arguments可选,被插件和一些broker的特定功能所使用

Bindings

绑定定义了Exchange和Queue之间的关系,是Exchanges用来路由消息到Queues时使用的规则,Queue必须绑定到Exchange才能收到消息。

绑定需要用到一个额外的routing_key的参数,为了防止和生产消息中的routing_key混淆,我们称之为binding key。binding key的定义也取决于Exchange的类型。Fanout Exchange会忽略binding key的值。

用相同的binding key绑定多个Queue是被允许的。例如上面一图所示:

direct_exchange_02.png

Message

AMQP消息含有以下属性:

  • Content type
  • Content encoding
  • Routing key
  • Delivery mode (persistent or not)
  • Message priority
  • Message publishing timestamp
  • Expiration period
  • Publisher application id

其中有一部分属性被broker使用,但大多数属性都可以通过接收它们的应用程序来进行解释。

Message Acknowledgements(消息确认)

由于诸如rabbitmq之类的消息代理的系统是分布式的,消息的发送和消费的过程中可能会造成消息的“丢失”。为了保证消息到达和被成功处理,publishers和consumers都需要一种交付和处理确认的机制。

Publisher Confirm

未完,有需要再学习补充

Consumer Ack

未完,有需要再学习补充

参考:

  1. AMQP 0-9-1 Model Explained
  2. Consumer Acknowledgements and Publisher Confirms