RabbitMQ 集群部署

对着背影说爱祢 提交于 2019-12-11 10:15:02

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

RabbitMQ 元数据

  • RabbitMQ 元数据类型
RabbitMQ 会始终记录以下类型的内部元数据:
    
    * 队列元数据 --- 队列名称和它们的属性(是否可持久化,是否自动删除)
    * 交换器元数据 --- 交换器名称,类型,属性(可持久化等)
    * 绑定元数据 --- 一张简单的表格展示如何将消息路由到队列
    * vhost 元数据 --- 为 vhost 内的队列,交换器和绑定提供命名空间和安全属性
    * 用户和用户权限信息元数据
  • 单节点元数据存储
RabbitMQ 会将所有的这些信息存储在内存中,同步将标记为可持久化的队列和交换器存储到硬盘上,从而确保队列和交换器在重启服务
的时候可以重建

  • 集群环境元存储
集群环境引入了新的元数据:集群节点位置,以及节点与已记录的其他类型元数据的关系,集群也提供了选择,将元数据存储到磁盘(独立节
点的默认配置)或者 RAM 中

集群中运行的任何一个节点,都拥有集群的全部元数据

集群中声明队列,交换器,绑定的时候,这些操作需要等到所有集群节点都成功提交元数据变更,才会返回

内存节点和磁盘节点

RabbitMQ 中的节点按存储方式分为两类:
    * 内存节点: 所有的元数据定义仅存储在内存中(不包含消息内容,消息索引,队列索引,其他节点状态),在频繁变更队列,交换器,绑定
    的情况下,使用内存节点可以提高性能
    * 磁盘节点: 所有的元数据存储在磁盘中

注意:

  1. 单节点系统只允许磁盘节点存在,集群环境可同时有两种节点

  2. RabbitMQ 要求集群中最少拥有一个磁盘节点

  3. 节点加入或者离开必须通知到至少一个磁盘节点,必须所有磁盘节点都是在线状态

  4. 如果所有磁盘节点都崩溃了,集群不再允许修改任何元数据

  5. 内存节点启动,会连接到磁盘节点下载集群元数据,只要内存节点能连接到一个磁盘节点,就可以加入到集群中

RabbitMQ 集群部署

注意: Clustering is meant to be used across LAN. It is not recommended to run clusters that span WAN.

环境准备

1.配置三台机器的 hosts 文件, hostname:

    192.168.32.61 rabbitmq1
    192.168.32.62 rabbitmq2
    192.168.32.63 rabbitmq3
  1. 安装 erlang, 解压 RabbitMQ 安装文件(同单节点安装)
  2. 同步 erlang cookie, 保证三台机器有相同的 erlang cookie:
    [root@rabbitmq1 ~]# cat ~/.erlang.cookie 
    AIKMCIGHSUKFZUODBIUD[root@rabbitmq1 ~]# 
在所有节点启动 RabbitMQ, 这三个节点目前没有任何关联
[root@rabbitmq1 sbin]# ./rabbitmq-server -detached
[root@rabbitmq2 sbin]# ./rabbitmq-server -detached
[root@rabbitmq3 sbin]# ./rabbitmq-server -detached
把rabbitmq2和rabbitmq3上的节点加入到rabbitmq1所在的集群中(目前单节点)

注意: join_cluster操作会先对当前节点执行 reset, 这会删除当前RabbitMQ所有的数据

  • rabbitmq2上操作
# 关闭 RabbitMQ
[root@rabbitmq2 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq2 ...

# 加入到集群中
[root@rabbitmq2 sbin]# ./rabbitmqctl join_cluster rabbit@rabbitmq1
Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1

# 启动 RabbitMQ
[root@rabbitmq2 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq2 ...
 completed with 0 plugins.
 
# 查看集群状态
[root@rabbitmq2 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq2 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq1,rabbit@rabbitmq2]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq1,[]},{rabbit@rabbitmq2,[]}]}]
  • 在rabbitmq3做相同操作
[root@rabbitmq3 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq3 ...
[{nodes,[{disc,[rabbit@rabbitmq3]}]},
 {running_nodes,[rabbit@rabbitmq3]},
 {cluster_name,<<"rabbit@rabbitmq3">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq3,[]}]}]
[root@rabbitmq3 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq3 ...
[root@rabbitmq3 sbin]# ./rabbitmqctl join_cluster rabbit@rabbitmq1
Clustering node rabbit@rabbitmq3 with rabbit@rabbitmq1
[root@rabbitmq3 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq3 ...
 completed with 0 plugins.
[root@rabbitmq3 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq3 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},
 {running_nodes,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq1,[]},{rabbit@rabbitmq2,[]},{rabbit@rabbitmq3,[]}]}]

集群部署完成

集群重启注意事项:

When the entire cluster is brought down, the last node to go down must be the first node to be brought online. If this
doesn't happen, the nodes will wait 30 seconds for the last disc node to come back online, and fail afterwards. If the last
node to go offline cannot be brought back up, it can be removed from the cluster using the forget_cluster_node command 
consult the rabbitmqctl manpage for more information.

If all cluster nodes stop in a simultaneous and uncontrolled manner (for example with a power cut) you can be left with a
situation in which all nodes think that some other node stopped after them. In this case you can use the force_boot command
on one node to make it bootable again - consult the rabbitmqctl manpage for more information.

从集群中移除节点,方法1:

  • 把rabbitmq3从集群中移除
[root@rabbitmq3 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq3 ...
[root@rabbitmq3 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq3 ...
[root@rabbitmq3 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq3 ...
 completed with 0 plugins.

  • 查看当前节点集群状态
[root@rabbitmq3 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq3 ...
[{nodes,[{disc,[rabbit@rabbitmq3]}]},
 {running_nodes,[rabbit@rabbitmq3]},
 {cluster_name,<<"rabbit@rabbitmq3">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq3,[]}]}]
  • 在其他节点上查看集群状态
[root@rabbitmq1 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq1]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]

从集群中移除节点,方法2:

先把 rabbitmq3 从新加入集群,测试用

  • 关闭 rabbitmq3 上的应用 RabbitMQ
[root@rabbitmq3 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq3 ...
  • 当前集群状态(注意 running nodes)
[root@rabbitmq1 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},
 {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq1]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]
  • 从集群中移除 rabbitmq3
[root@rabbitmq1 sbin]# ./rabbitmqctl forget_cluster_node rabbit@rabbitmq3
Removing node rabbit@rabbitmq3 from the cluster
  • 操作结果
[root@rabbitmq1 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq1]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]

注意: rabbitmq3 虽然被从集群中移除,但是 rabbitmq3 节点本身并不知道,因此启动会报错,需要进行 reset 操作才能正常启动

内存节点操作

当前状态,三个节点没有任何关系,处于未配置集群的初始状态

  • 启动 rabbitmq1
[root@rabbitmq1 sbin]# ./rabbitmq-server  -detached
Warning: PID file not written; -detached was passed.

# 集群当前状态
[root@rabbitmq1 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1]}]},
 {running_nodes,[rabbit@rabbitmq1]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq1,[]}]}]
  • rabbitmq2 以内存节点的形式加入
[root@rabbitmq2 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq2 ...

# --ram 表示当前节点的类型为内存节点
[root@rabbitmq2 sbin]# ./rabbitmqctl join_cluster rabbit@rabbitmq1 --ram
Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1
  • 查看结果
[root@rabbitmq2 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq2 ...
 completed with 0 plugins.
 
[root@rabbitmq2 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq2 ...
[{nodes,[{disc,[rabbit@rabbitmq1]},{ram,[rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq1,rabbit@rabbitmq2]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq1,[]},{rabbit@rabbitmq2,[]}]}]
  • rabbitmq3 以内存节点的形式加入
省略
  • 查看集群状态
[root@rabbitmq3 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq3 ...
 completed with 0 plugins.
[root@rabbitmq3 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq3 ...
[{nodes,[{disc,[rabbit@rabbitmq1]},{ram,[rabbit@rabbitmq3,rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq1,rabbit@rabbitmq3]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]},{rabbit@rabbitmq3,[]}]}]
  • 修改rabbitmq2为磁盘节点
[root@rabbitmq2 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq2 ...
[root@rabbitmq2 sbin]# ./rabbitmqctl change_cluster_node_type disc
Turning rabbit@rabbitmq2 into a disc node
[root@rabbitmq2 sbin]# ./rabbitmqctl start_app
Starting node rabbit@rabbitmq2 ...
 completed with 0 plugins.
[root@rabbitmq2 sbin]# ./rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq2 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]},{ram,[rabbit@rabbitmq3]}]},
 {running_nodes,[rabbit@rabbitmq1,rabbit@rabbitmq3,rabbit@rabbitmq2]},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq1,[]},{rabbit@rabbitmq3,[]},{rabbit@rabbitmq2,[]}]}]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!