Exchange
本文介绍云消息队列 RabbitMQ 版的Exchange的概念和类型,帮助您理解和选择Exchange。
什么是Exchange
Exchange是云消息队列 RabbitMQ 版的消息路由代理。生产者向云消息队列 RabbitMQ 版发送消息时,不会直接将消息发送到Queue,而是先将消息发送到Exchange,由Exchange将消息路由到一个或多个Queue。Exchange根据Routing Key和Headers属性路由消息。
Direct Exchange
路由规则
Direct Exchange根据Routing Key完全匹配的规则路由消息。
使用场景
Direct Exchange适用于通过简单字符标识符区分消息的场景。Direct Exchange常用于单播路由。
匹配示例
Direct Exchange根据Routing Key完全匹配的规则路由消息的示例如下:
Message
Routing Key
绑定关系中的Routing Key
Queue
Message A
img.create
img.create
Queue A
Message B
img.log
img.log
Queue B
Topic Exchange
路由规则
Topic Exchange根据Routing Key通配符匹配的规则路由消息。Topic Exchange支持的通配符包括星号(*)和井号(#)。星号(*)代表一个英文单词(例如cn)。井号(#)代表零个、一个或多个英文单词,英文单词间通过英文句号(.)分隔,例如cn.zj.hz。
使用场景
Topic Exchange适用于通过通配符区分消息的场景。Topic Exchange常用于多播路由。例如,使用Topic Exchange分发有关于特定地理位置的数据。
路由示例
Topic Exchange根据Routing Key通配符匹配的规则路由消息的示例如下:
Message
Routing Key
绑定关系中的Routing Key
Queue
Message A
files.cn.hz
files.cn.hz.#
Queue A
Message B
files.cn.hz.store
files.cn.hz.#
files.cn.*.store
Queue A
Queue B
Message C
files.cn.sz.store
files.cn.*.store
Queue B
Fanout Exchange
路由规则
Fanout Exchange忽略Routing Key的匹配规则将消息路由到所有绑定的Queue。
使用场景
Fanout Exchange适用于广播消息的场景。例如,分发系统使用Fanout Exchange来广播各种状态和配置更新。
路由示例
Fanout Exchange忽略Routing Key的匹配规则将消息路由到所有绑定的Queue的示例如下:
Message
Routing Key
绑定关系中的Routing Key
Queue
Message A
img.create
files.cn.hz.#
queue.msgText
Queue A
Queue B
Message B
queue.msgMap
files.cn.hz.#
queue.msgText
Queue A
Queue B
Message C
cn.hz.topic.alarm
files.cn.hz.#
queue.msgText
Queue A
Queue B
Headers Exchange
路由规则
Headers Exchange可以被视为Direct Exchange的另一种表现形式。Headers Exchange可以像Direct Exchange一样工作,不同之处在于Headers Exchange使用Headers属性代替Routing Key进行路由匹配。您在绑定Headers Exchange和Queue时,可以设置绑定属性的键值对。然后,在向Headers Exchange发送消息时,设置消息的Headers属性键值对。Headers Exchange将根据消息Headers属性键值对和绑定属性键值对的匹配情况路由消息。
匹配算法由一个特殊的绑定属性键值对控制。该属性为x-match,只有以下两种取值:
all:所有除x-match以外的绑定属性键值对必须和消息Headers属性键值对匹配才会路由消息。
any:只要有一组除x-match以外的绑定属性键值对和消息Headers属性键值对匹配就会路由消息。
以下两种情况下,认为消息Headers属性键值对和绑定属性键值对匹配:
消息Headers属性的键和值与绑定属性的键和值完全相同。
消息Headers属性的键和绑定属性的键完全相同,但绑定属性的值为空。
使用场景
Headers Exchange适用于通过多组Headers属性区分消息的场景。Headers Exchange常用于多播路由。例如,涉及到分类或者标签的新闻更新。
使用示例
Headers Exchange根据消息Headers属性和Binding Headers属性的匹配规则路由消息的示例如下:
Message
消息Headers属性
Binding Headers属性
Queue
Message A
type=read resource=group
type=read resource=group x-match=all
type=read resource=topic x-match=any
Queue A
Queue B
Message B
type=read
type=read resource=topic x-match=any
Queue B
Message C
type=write resource=topic
type=read resource=topic x-match=any
Queue B
JMS Queue Exchange
除AMQP协议约定的Exchange外,云消息队列 RabbitMQ 版还支持JMS Queue Exchange。JMS Queue Exchange本质上就是Direct Exchange。云消息队列 RabbitMQ 版通过JMS Queue Exchange来实现JMS规范约定的Queue。
该类Exchange只能通过SDK创建。
路由规则
JMS Queue Exchange根据Routing Key完全匹配的规则路由消息。
使用场景
JMS Queue Exchange适用于通过简单字符标识符区分消息的场景。JMS Queue Exchange常用于单播路由。
使用示例
JMS Queue Exchange根据Routing Key完全匹配的规则路由消息的示例如下:
Message
Routing Key
绑定关系中的Routing Key
Queue
Message A
queue.msgText
queue.msgText
Queue A
Message B
queue.msgMap
queue.msgMap
Queue B
Message C
queue.msgObj
queue.msgObj
Queue C
JMS Topic Exchange
除AMQP协议约定的Exchange外,云消息队列 RabbitMQ 版还支持JMS Topic Exchange。JMS Topic Exchange本质上就是Topic Exchange。云消息队列 RabbitMQ 版通过JMS Topic Exchange来实现JMS规范约定的Topic。
路由规则
JMS Topic Exchange根据Routing Key通配符匹配的规则路由消息。JMS Topic Exchange支持星号(*)和井号(#)。星号(*)代表一个英文单词(例如cn)。井号(#)代表零个、一个或多个英文单词,英文单词间通过英文句号(.)分隔(例如cn.zj.hz)。
使用场景
JMS Topic Exchange适用于通过通配符区分消息的场景。JMS Topic Exchange常用于多播路由。例如,使用JMS Topic Exchange分发有关于特定地理位置的数据。
使用示例
JMS Topic Exchange根据Routing Key通配符匹配的规则路由消息的示例如下:
Message
Routing Key
绑定关系中的Routing Key
Queue
Message A
cn.hz.instance
cn.hz.instance.#
Queue A
Message B
cn.hz.instance.alarm
cn.hz.instance.#
cn.hz.*.alarm
Queue A
Queue B
Message C
cn.hz.topic.alarm
cn.hz.*.alarm
Queue B
x-delayed-message Exchange
云消息队列 RabbitMQ 版还兼容开源RabbitMQ以插件形式支持的x-delayed-message Exchange。您无需安装该插件,只需声明该类Exchange,并自定义消息的Header属性x-delay来指定消息延时投递的时间段,单位为毫秒。消息将在x-delay定义的时间段后被投递到对应的Queue。
路由规则
x-delayed-message Exchange根据扩展字段x-delayed-type指定的Exchange类型确定路由规则。支持x-delayed-message的Exchange类型如下:
使用场景
x-delayed-message Exchange适用于需要延时投递消息的场景。更多信息,请参见延时消息。
使用示例
x-delayed-message Exchange根据x-delayed-type指定的Exchange类型的路由规则路由消息。以x-delayed-type指定为Direct类型为例,Direct Exchange根据Routing Key完全匹配的规则路由消息的示例如下:
Message
x-delay
Routing Key
绑定关系中的Routing Key
Queue
Message A
3000
img.create
img.create
Queue A
Message B
4000
img.log
img.log
Queue B
消息路由说明如下:
Message A到达Exchange后,x-delayed-message Exchange会在3000毫秒后将Message A投递至Queue A。
Message B到达Exchange后,x-delayed-message Exchange会在4000毫秒后将Message B投递至Queue B。
x-consistent-hash Exchange
云消息队列 RabbitMQ 版兼容开源RabbitMQ以插件形式支持的x-consistent-hash Exchange。您无需安装该插件,只需声明该类Exchange。
x-consistent-hash Exchange暂不支持基于hash-property的方式进行路由,即不支持按照message id、correlation id、timestamp的方式计算哈希路由。
路由规则
x-consistent-hash Exchange支持基于Routing Key或Header值两种方式进行路由。Exchange收到消息后,会根据消息的Routing Key或Header值进行Hash运算,由计算的Hash值决定消息路由到哪个绑定的Queue中。
同一Routing Key或Header值计算的Hash值相同,因此,相同Routing Key或Header值的消息会被路由到同一个Queue中。
使用Header值的方式进行路由匹配时,需要通过hash-header字符串声明Exchange、声明要使用的Header。同时发布的消息需要包含hash-header所选的Header,若未包含指定的Header,则全部消息将被路由到同一个任意队列中。
若Routing Key和hash-header参数同时定义,则以hash-header参数值为输入进行Hash运算。
x-consistent-hash Exchange绑定Queue时,Routing Key需要设置为1~20的数字,表示该Queue的权重。数值越大权重越大,分发消息时接收到的消息越多。
当Queue的Routing Key大于20时,权重会视为20。
当存在重复绑定时,只有第一个符合要求的绑定(绑定值为正整数)有效;修改Queue的权重时,请先删除已有的绑定关系。
使用场景
x-consistent-hash适合按照权重对消息进行划分的场景。
使用示例
x-consistent-hash Exchange根据消息的指定方式计算哈希进行路由。Exchange上绑定有不同权重的Queue,并根据Queue的权重将消息分发到不同的Queue中。本示例以基于Routing Key方式计算路由规则为例。
Message
Routing Key
Message A
cn.hz.1
Message B
cn.hz.2
Message C
cn.hz.3
Queue
绑定关系中的Routing Key
Queue A
1
Queue B
2
路由说明如下:
Message A、Message B、Message C到达Exchange后,将按照其Routing Key计算哈希值,并按照哈希值投递到Queue中。
Exchange分别绑定了Queue A和Queue B,且权重为1和2,因此消息将按照1∶2的权重路由到Queue A和Queue B中。