Rabbitmq

rabbitmq集群小记

2018-03-14  本文已影响240人  开心就好_4ad7

一、背景

      RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现,虽然我自己在项目使用公司rabbitMQ消息中间件,但对于rabbitmq集群的原理,了解不比较散,现简单总结一下。

二、集群目的

       集群的目的,无非就两个,一是允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行,二是通过增加更多的节点来扩展消息通信的吞吐量。

三、集群方式

       rabbitmq集群主要有三种,分别是:cluster,federation,shovel,下面分别介绍一下这几种集群的配置方式。

(1)cluster

   不支持跨网段,用于同一个网段内的局域网。

    可以随意的动态增加或者减少node。

    节点之间需要运行相同版本的RabbitMQ和Erlang。

(2)federation

         应用于广域网,允许单台服务器上的交换机或队列接收发布到另一台服务器上交换机或队列的消息,可以是单独机器或集群。federation队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受。通常使用federation来连接internet上的中间服务器,用作订阅分发消息或工作队列。

(3)shovel

         连接方式与federation的连接方式类似,但它工作在更低层次,也可以应用于广域网。

四、节点类型

rabbitmq节点类型主要是内存节点(ram node)和磁盘节点(disk node)。

RAM node:内存节点将所有的队列、交换机、绑定、用户、权限和vhost的元数据定义存储在内存中,好处是可以使得像交换机和队列声明等操作更加的快速。

Disk node:将元数据存储在磁盘中,单节点系统只允许磁盘类型的节点,防止重启RabbitMQ的时候,丢失系统的配置信息。

     RabbitMQ要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入或者离开集群时,必须要将该变更通知到至少一个磁盘节点。如果集群中唯一的一个磁盘节点崩溃的话,集群仍然可以保持运行,但是无法进行其他操作(增删改查),直到节点恢复。解决方案:设置两个磁盘节点,至少有一个是可用的,可以保存元数据的更改。

五、集群node通讯

       RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证。而Erlang Cookie是保证不同节点可以相互通信的密钥,要保证集群中的不同节点相互通信必须共享相同的Erlang Cookie。具体的目录存放在/var/lib/rabbitmq/.erlang.cookie。

六、集群模式

       RabbitMQ的Cluster集群模式分为两种,普通模式和镜像模式。

        普通模式:默认的集群模式,对于Queue来说,消息实体只存在于其中一个节点,对于集群上的所有节点仅有相同的元数据,即队列的结构。当消息进入集群中某个节点的Queue后,consumer从另外一个节点消费时,比如node1、node2两个节,RabbitMQ会临时在node1、node2间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连或node1还是node2,出口总在node1,会产生瓶颈。当node1节点故障后,node2节点无法取到node1节点中还未消费的消息实体。如果做了消息持久化,那么得等node1节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。

          镜像模式:将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现RabbitMQ的HA高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在consumer消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。镜像队列实现了RabbitMQ的高可用性(HA),具体的实现策略如下:

all:镜像队列将会在整个集群中复制。当一个新的节点加入后,也会在这 个节点上复制一份。

exactly( count):镜像队列将会在集群上复制count份。如果集群数量少于count时候,队列会复制到所有节点上。如果大于Count集群,有一个节点crash后,新进入节点也不会做新的镜像。

nodes( node name): 镜像队列会在node name中复制。如果这个名称不是集群中的一个,这不会触发错误。如果在这个node list中没有一个节点在线,那么这个queue会被声明在client连接的节点。

上一篇 下一篇

猜你喜欢

热点阅读