RabbitMQ in Action(二)

RabbitMQ集群

集群架构

RabbitMQ始终记录以下4种类型的数据

  • 队列元数据:队列名称、属性(是否持久化,是否自动删除)。
  • 交换器元数据:交换器名称、类型、属性(是否持久化)。
  • 绑定元数据:消息路由到队列的规则。
  • vhsot元数据:为vhost内的队列、交换器和绑定提供命名空间和安全属性。

在单一结点内,RabbitMQ会将以上所有信息存储在内存中,同时将被标记为可持久化的队列、交换器和它们的绑定存储到硬盘上。

集群中的队列

在集群中创建队列,只会在单个节点而不是所有的节点上创建完整的队列信息,只有队列的所有者拥有队列的所有信息,非所有者节点只拥有队列的元数据和指向该队列存在的节点的指针。存储空间和性能考虑

集群中的交换器

集群中每个节点拥有每个交换器的完整信息。

集群中的节点

内存节点和磁盘节点

  • 单节点系统只允许磁盘类型的节点,否则每次重启后,所有关于系统的配置信息都会丢失。
  • 集群中至少有一个磁盘节点,当节点加入或离开集群时,必须要将变更通知到至少一个磁盘节点。
  • 集群中唯一磁盘节点奔溃,集群仍可保持运行,但其恢复前不能执行更改操作
  • 当需要添加或删除集群节点时,所有的磁盘节点必须在线。

集群配置

配置前

  • 关闭节点:rabbitmqctl stop

启动前

  • 禁用插件:防止插件监听的端口产生冲突。

调用rabbitmq-server

  • 设置节点名称:环境变量RABBITMQ_NODENAME
  • 设置端口:环境变量BABBITMQ_NODE_PORT

启动节点
BABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit rabbitmq-server -detached(默认端口:5672,默认节点名称:rabbit)

  • 停止RabbitMQ应用程序:rabbitmqctl -n rabbit_1@hostname stop_app
  • 清空元数据,重置节点状态:rabbitmqctl -n rabbit_1@hostname reset
  • 加入到第一个集群节点:rabbitmqctl -n rabbit_1@hostname cluster rabbit@hostname rabbit_1@hostname-n参数:在指定节点上执行命令而非默认节点;cluster后面的参数:指定集群中的磁盘节点。
  • 启动RabbitMQ应用程序:rabbitmqctl -n rabbit_1@hostname start_app

查看集群rabbitmqctl cluster_status

升级集群

  • 备份配置
  • 关闭生产者
  • 等待消费者消费完成队列(排空操作,2.6.0+后可不进行)

镜像队列(2.6.0+)

镜像队列的主拷贝仅存在一个节点(主队列,master)上,可在集群中其它节点上拥有从队列(slave)拷贝。
若队列主节点不可用,最老的从队列将被升级为新的主队列。

声明镜像队列

  • 设置声明队列时的参数:x-ha-policy
  • queue_args={"x-ha-policy":"all"}all指定镜像到集群中的所有节点上
  • channel.queue_declare(queue="queue_name",arguments=queue_args)

查看队列的镜像信息

  • rabbitmqctl list_queue name pid slave_pids,参数分别为:队列名称,队列主拷贝的Erlang进程ID,其它节点的从拷贝列表

指定镜像的目标节点(2.7.0+)

  • 设置声明队列时的参数:x-ha-policyx-ha-policy-params
  • queue_args={"x-ha-policy":"nodes","x-ha-policy-params":["rabbit@hostname"]}all指定镜像到集群中的所有节点上
  • channel.queue_declare(queue="queue_name",arguments=queue_args)

新增的从拷贝只会存在自身被添加后从镜像队列发来的消息,(2.7.0前)不会和已存在的内容进行同步。旧消息消费后队列拷贝才会一致。

检测已有的队列拷贝是否一致

  • 列出队列时增加参数:synchronised_slave_pids
  • rabbitmqctl list_queue name pid slave_pids sychronised_slave_pids,查看括号内pids是否一致即可。一致时才可从集群中移除节点

镜像队列工作原理

镜像队列中

  • 消息-(路由绑定规则)→合适的队列 && 镜像队列的从拷贝。
  • 所有队列和队列的从拷贝安全地接收到消息后确认收到。

主拷贝节点故障

  • 该队列的消费者→重新附加并监听新的队列主拷贝。
  • 连接到故障节点的消费者(直连):失去TCP连接,重新附加到集群中新节点,自动选取新的队列主拷贝。
  • 连接通过该节点附加的镜像队列的消费者:将收到Rabbit的取消通知。若AMQP客户端支持通知,则抛出异常,且重新附加;若不支持通知,未消费的消息将塞满队列。

因此,如果客户端库不支持消费者取消通知的话,应该避免使用镜像队列。

安全起见:已经消费但尚未被确认的消息会重入队到它们原来所在的队列位置。(2.7.0前)

你可能感兴趣的:(RabbitMQ in Action(二))