(3)RabbitMQ集群跨越
RabbitMq跨越集群的界限
RabbitMq分布式搭建的方案有:集群、Federation、Shovel。该三种搭建集群的方式不是互斥的,可以进行组合的方式进行使用。
Federation
Federation插件的设计目标是使RabbitMQ在不同的broker节点之间进行消息传递,而无需建立集群。该功能的使用场景如下:
- 可以在不同的域下的Broker或者集群当中传递消息
- 能容忍网络不佳的情况
- 一个Broker节点可以同时存在联邦交换器或者本地交换器。只需要特定的交换器或者队列创建Federation链接即可
- Federation不需在N个Broker节点之间创建多个链接,使用起来易于扩展
1.联邦交换器
案例如下:
目前有broker1 部署在北京,broker2部署在上海,broker3部署在广州。广州的ClientA需要连接接broker3.并向其中的exchangeA发送消息,此时的网络延迟很小。ClientA可以很快的将消息发送到exchangeA中。此时有一个ClientB也需要向exchange3中发送消息,clientB位于北京的业务,clientB和broker3之间存在着较大的网络延迟。ClientB在发送到exchange3的时候由于网络延迟,所以导致该线程的性能下降,会造成一定时间的阻塞。
如何优化,服务器放在一起?放在一起容灾无法实现。
对于该应用场景的发生使用Fderation插件的方式可以非常好的解决。Fderation在broker3的交换器exchangeA创建一条于北京的broker单向的Fderation link。此时Fderation 插件会在broker1上面创建一个同名
exchanegA
的交换器。同时创建一个内部的交换器exchangeA->broker 3 B
并且通过路由键K1进行绑定。同时还会再broker1上建立一个队列federation:exchangeA ->broker3 B
并于交换器exchangeA->broker3 B
进行绑定。Federation插件会在队列federation:exchangeA->broker3 B
与broker3当中的exchangeA创建一条AMQP链接来实时消费队列federation:exchangeA->broker3 B
中的数据。可以分为如下几步建立Fderation link连接:
- broker1创建一个exchangeA 交换器
- broker1内部创建一个交换器 exchangeA与broker3 B 绑定,通过路由键的方式进行绑定
- broker1创建队列
federation:exchangeA->broker3 B
,与交换器exchangeA->broker3 B
进行绑定
federation:exchangeA->broker3B
与broker3当中的exchangeA交换器建立一条AMQP链接,实时消费federatio:exchangeA->broker3
的数据。2. 联邦队列(federated queue)
联邦队列可以在多个Broker节点之间为单个队列提供负载均衡功能。一个联邦队列可以链接一个或者多个上游队列,并从这些上游队列中获取消息以满足本地消费者消费信息的需求。和联邦交换器不同,一条消息可以在联邦队列之间转发
无限次
,队列中的消息除了被消费,还会转向有多余消费能力的乙方,如果这种"消费能力"在broker1和broker2来回切换,那么消费者也会在broker1和broker2的队列中来回转发。注意: 理论上一个federated的queue与一个federated exchange绑定起来,不过这样可能会导致一些无法预测的结果,所以不太建议如此搭配使用。
Shovel
与Federation具备的数据转发功能类似,Shovel能够可靠,持续地从一个Broker中的队列拉取数据并转发至另一个Broker中的交换器。
Shovel的主要优势为:
- 松耦合: Shovel可以移动位于不同管理域中的Broker,这些Broker可以包含不同用户和vhost,也可以使用不同的RabbitMQ和Erlang版本。
- 支持广域网。 Shovel插件同样基于AMQP协议在Broker之间进行通信,被设计成可以容忍时断时序的连通情形,并且能够保证消息的可靠性
- 高度定制 大哥Shovel成功连接后,可以对其进行配置以及执行相关的AMQP命令。
Shovel的原理:
1626873345.png
- broker1当中创建一个exchange1 ,和一个queue1 他们之间通过rk1进行绑定。
- broker2当中有一个exchange2,一个queue2,通过rk2进行绑定。在队列queue1和交换器exchange2之间配置一个Shovel link
- 当客户端X发送消息至exchange1,exchange1经过queue1,再从quue1当中 发送到broker2中的exchange2
- exchange2 存储到queue2 最终数据存储落在了broker2的queue2
通常情况一般配置queue为源端,exchange为目的断。Shovel可以为源端配置多个Broker地址,当一个Broker地址失效后还可以尝试其它的broker地址
消息堆积的治理
消息堆积是在使用消息中间件遇到的很正常的问题,消息 堆积是一把双刃剑,适量的堆积可以削峰、缓存的作用,如果堆积过于严重,会影响到其他队列的使用。当一台普通服务器,一个队列中堆积1w-10w不会产生什么影响,但是当消息数量达到1000w或者更多的时候,可能会遇到一些问题。
- 当检测到当前运行集群cluster1中的队列queue1中有严重消息堆积,可以通过/api/quues/vhost/name接口获取到队列的消息个数超过2000w或者消息大小超过10GB.就启用shovel1将队列消息转发到备份集群 cluster2的queue2.
- 当检测队列queue1中的消息个数低于100w,或者消息占用大小低于10GB的时候就停止shovel1,然后让原本队列queue1中的消费者慢慢处理剩下的数据
- 当检测队列queue1中的消息个数低于10w或者消息占用大小低于100MB的时候,就开启Shovel2将队列queue2中暂存的消息返还给队列queue1
- 当检测到队列queue1中的消息个数超过100w或者消息占用大小高于1GB时,就停止shovel2.
Federation/sShovel | 集群 |
---|---|
各个Borker节点之间逻辑分离 | 逻辑上是一个Broker |
各个Broker节点之间可以运行同版本的Erlange和RabbitMQ | 各个Broker节点直接的Erlang和RabbitMQ必须一致 |
各个Broker节点之间可以在广域网当中链接,需要授权 | 各个Broker节点之间必须在可信任的局域网中相连,通过Erlang内部节点传递消息,但节点需要有相同的Erlang cookie |
各个Broker节点之间能以任何拓扑的逻辑部署,链接可以是单向或者双向 | 所有Broker节点都双向链接所有其他节点 |
从CAP理论中选择可用性和分区耐受性,即AP | 从CAP理论中选择一致性和可用性。CA |
一个Broker中的交换器可以是Federation生成的也可以是本地的 | 集群中所有的Broker节点的交换器是一样的,要么全有要么全无 |
客户端所能看到的所连接的broker队列 | 客户端链接到的集群中的任何Broker节点都可以看到所有的队列 |