【RabbitMQ】Federation实现消息传递
创始人
2025-05-29 05:00:42
0

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系列文章会陆续更新,欢迎各位小伙伴关注后面的技术分享。

相关内容

热门资讯

爱的教育作文 爱的教育作文爱的教育看到这个书名,我不禁开始思考一个问题:在这个缤纷多彩的世界里,爱究竟是什么含义?...
梁衡《把栏杆拍遍》读书笔记 梁衡《把栏杆拍遍》读书笔记梁衡《把栏杆拍遍》读书笔记这是一篇写得很美的散文,有以下特点:一、联想丰富...
【每日一题Day150】LC1... 分割两个字符串得到回文串【LC1616】 给你两个字符串 a 和 b ,它们长度相同...
一年级春游日记 一年级春游日记一年级春游日记1  今天是春游,我作天就去买许多零食和矿泉水,打算在春游的时候干掉,我...
课外读书笔记摘抄 课外读书笔记摘抄(精选12篇)  导语:舍弃就是这样,它也许出于无奈,可在无奈之后是另一份希望,它也...
蚂蚁观察日记 【热门】蚂蚁观察日记4篇蚂蚁观察日记 篇1  我家有一个后院,我经常到后院去观察那些鹭绿上得小精灵—...
ImageView(图像视图) 本节介绍的UI基础控件是:ImageView(图像视图),就是用来显示图像的一个View或者说控件!...
关于接口测试——自动化框架的设... 一、自动化测试框架 在大部分测试人员眼中只要沾上“框架”,就感觉非常神秘,...
【2023.3.8】数据结构复... 【2023.3.8】数据结构复习笔记 文章目录【2023.3.8】数据结构复习笔记序言一、绪论二、线...
数学周记 【精华】数学周记范文(通用20篇)  不经意间,一个星期已经结束了,想必有很多难忘的瞬间吧,是时候仔...
男生贾里全传读书笔记 男生贾里全传读书笔记(通用24篇)  当品读完一部作品后,相信大家一定领会了不少东西,不能光会读哦,...
1.计算机网络和因特网 1.因特网的描述1.1 具体构成描述根据底层实现(硬件软件)端系统(主机...
使用YOLO部署哨岗相机 流程 一.模型选取 将YOLO和Faster RCNN进行搭配,通过多次实验ÿ...
大蒜观察日记 大蒜观察日记3篇  【导语】大蒜虽然是一种很不起眼的植物,但是它的生命力很强,无论在任何的环境下都可...
四年级观察植物的日记 四年级观察植物的日记范文  观察植物的日记需要怎么写呢?同学们是否有观察过植物的生长过程呢?不妨写下...
同一片天空共眠,同一个梦想奋斗... 同一片天空共眠,同一个梦想奋斗《大抠车始歌》(1) Eng...
Vue 3.0 Data选项 #概览 非兼容:data 组件选项声明不再接收纯 JavaScript object...
Java中原子操作的实现原理 Java中原子操作的实现原理1. 什么是原子操作2. 处理器如何是实现操作的原子性2.1 使用总线锁...
春节的街头小学日记 春节的街头小学日记  今天是大年初一,天气晴朗,妈妈带着我一早来到了兴宁路。  街上可热闹了,车水马...
通用实习日记 通用实习日记集合10篇通用实习日记 篇1  4 月18 日  今天是为期三周实习的第一天,心情有点紧...