【RabbitMQ】Federation实现消息传递

RabbitMQ集群对时间非常敏感,应该在局域网中使用,不应在关于网中使用。而Federation插件可以很好地解决这个问题。这篇文章和大家分享RabbitMQ Federation的使用场景、实现原理和具体用法。

使用场景

Federation插件的目的就是解决RabbitMQ节点之间进行消息传递而不需要建立集群,这个功能在很多场景中都很有用:

  1. 在不同管理域(不同的用户、不同的vhost、不同的Rabbit版本)的节点、集群或者数据中心之间传递消息。
  2. 在不同的Broker之间进行通信时,需要解决网络的不稳定因素。
  3. 需要更高的扩展性。

以上只是列举了三个适用场景,了解它可以做什么,下面介绍它是如何做到的,也就是实现原理。

实现原理

Federation可以让多个交换器或者多个队列进行联邦,一个Federation Exchange或者一个Federation Queue可以接受其它Broker上的消息。Federation Exchange能够将原本发送其它Broker上的消息路由到本地队列中,Federation Queue允许本地Consumer消费其它Broker 队列上的消息。

下面结合一个例子介绍Federation的原理。如下图,假设有两个数据中心DC1和DC2,分别部署了RabbitMQ服务,Broker1和Broker2,DC1中的Clinet1向Broker1发送消息,由于是在一个DC,所以很快,如果Client1想DC2中的Broker2发送消息,就会有一定的网络延时,尤其是在开启了Publisher Confirm或者事务的情况下,甚至会造成一定的阻塞。此时,可以用Federation解决。

先看下面一张图。在Broker2上声明Exchange:federation_exchange,Queue:federation_queue,通过绑定键 federation_routing_key 将Exchange和Queue绑定,然后通过操作(下面演示)创建Federation Link,那么Federation插件会自动在Broker1上创建一个相同名字的Exchange:federation_exchange, 还会创建一个内部Exchange:"federation: federation_exchange -> rabbit02@LM-SHB-40513514 A","rabbit02@LM-SHB-40513514 A" 是Broker2所在集群的名字,通过federation_routing_key 将 federation_exchange 和 "federation: federation_exchange -> rabbit02@LM-SHB-40513514 A" 绑定,同时会自动创建内部Queue:"federation: federation_exchange -> rabbit02@LM-SHB-40513514" ,和内部Exchange绑定。

通过RabbitMQ UI可以观察到创建的federation exchange , federation queue,和它们绑定关系的详细信息,如下图。

  

当Client1发送消息到Broker1,Consumer2就可以消费到Broker2上federation_queue中的消息,消息的流转过程如下图。

 经过federation link转发的消息,header部分会有特殊的属性值,如下图。

Broker1的"federation: federation_exchange -> rabbit02@LM-SHB-40513514" 也是一种普通队列,Consumer1可以直接消它上面的消息,需要注意的是:如果发往Broker1 federation_exchange 的消息需要转发到Broker2上 federation_queue,那么"federation: federation_exchange -> rabbit02@LM-SHB-40513514"就不能有Consumer。

另外federation exchange可以成为其它节点上exchange的upstream exchange,而且还能互为upstream exchange,此时max_hops 参数表示一条消息最多被转发的此时为1。

 

除了federation exchange,还有federation queue,其实现原理类似,如下图,broker2上常见queue1和queue2,然后创建federation link,federation插件会自动在broker1上创建两个相同名字的queue1和queue2,并且分别对应有一条federation link,consumer2订阅broker2上的queue1或queue2,也能消费到broker1上的queue1或者queue2上的消息。

需要注意的是:加入broker2上的队列本身有消息堆积,那么broker2上的队列不会从broker1上的队列拉取消息,如果broker2上队列堆积的消息被消费完了,才会从broker1上拉取消息到本地。

但和federation exchange总结了以下三点不同:

  1. 一条消息可以在互为federation queue的队列上转发无限次,而federation exchange 不行。
  2. federation queue 只能用basic.consumer 方法来消费,不能有basic.get 方法消费。
  3. federation qeueu不具备传递性,如下图,queue1作为queue2的upstream queue(queue2是federation queue),queue2又作为queue3的upstream queue,但是queue3无论处于何种状态,都不会消费到queue1的消息。

如何使用

federation exchange或 federation queue 可以理解为 consumer,接收上游系统的消息,federation link是由创建federation 的节点主动发起连接,连到上游系统。

哪个节点作为consumer,接受上游的消息,就在哪个节点上创建federation。

单节点或者集群中,每个节点都需要开启 federation 插件。

如上例中,broker2上创建的federation link,那么broker2相当于broke1的consumer,broker1是broker2的上游系统。如果是在DC1和DC2中部署的集群,那么DC1和DC2的集群中的每个节点都需要启动federation插件。

下面是具体步骤。

 开启federation 插件

在每个节点中启用federation插件,为方便观察,同时启用federation UI。

rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management

# 如果自定义了broker名字,需要使用 -n 参数指定broker名字
./rabbitmq-plugins --node rabbit01@localhost enable rabbitmq_federation rabbitmq_federation_management

./rabbitmq-plugins --node rabbit02@localhost enable rabbitmq_federation rabbitmq_federation_management

定义upstream 

在broker2中定义upstream为broker1

./rabbitmqctl -n rabbit02@localhost  set_parameter  federation-upstream  my_upstream '{"uri":"amqp://guest:guest@localhost:5672", "ack-mode":"on-confirm"}'

创建policy

使用上面的定义的upstream,创建policy,匹配所有以 federation_exchange 开头的交换器,都创建对应的federation exchange。

./rabbitmqctl -n rabbit02@localhost  set_policy  --apply-to exchanges  my_policy "^federation_exchange" '{"federation-upstream":"my_upstream"}'

producer发布消息

Porducer可以发布消息到borker1上的 federation_exchange,代码和发送到普通交换器的代码一样,可以参考之前的文章,有很多实例代码。

consumer消费消息

Consumer可以订阅broker2上的federation_queue,代码也和普通Consumer订阅Queue的代码一样,可以参考以前的文章,有很多的实例。

好了,以上就是关于RabbitMQ Federation的使用场景、原理和使用方法的介绍了,federation queue的操作方式类似,有兴趣的小伙伴可以自己实验。

RabbitMQ系列文章会陆续更新,欢迎各位小伙伴关注后面的技术分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值