[Erlang 0086] RabbitMQ 集群: 从零开始

简介:

 之前文章介绍了RabbitMQ的metadata, 元数据可以持久化在RAM或Disc.从这个角度可以把RabbitMQ集群中的节点分成两种:RAM Node 和 Disk Node. RAM Node只会将元数据存放在RAM,Disc node 会将元数据持久化到磁盘.

   单节点系统就没有什么选择了,只允许disk node,否则由于没有数据冗余一旦重启就会丢掉所有的配置信息.但在节点环境中可以选择哪些节点是RAM node.

 

 

Check First

 

  RabbitMQ Cluster的部署非常方便,有一些需要注意的细节,只要做过Erlang节点互连的,这些也都是耳熟能详的了:

[1] 统一 Erlang Cookie; 虽然官方网站上提到了修改.erlang.cookie的方式,不过我从来没有这样做过,都是启动erlang node的时候使用  -setcookie  显示指定cookie;这样做的影响就是rabbitmqctl由于没有指定cookie不能正常使用了,可以同样修改一下添加-setcookie.这里为了方便我拷贝rabbitmqctl新建了一个工具rabbitmq-util指定了cookie.如下:

复制代码
exec erl \
    -pa "${RABBITMQ_HOME}/ebin" \
    -noinput \
    -hidden \
    ${RABBITMQ_CTL_ERL_ARGS} \
    -setcookie  zen_rabbitmq \
    -name rabbitmqctl@zen.com \
    -s rabbit_control \
    -nodename $RABBITMQ_NODENAME \
    -extra "$@"
复制代码

   需要统一erlang cookie的脚本有:rabbitmqctl  rabbitmq-server

 

[2] 如果使用sname创建Erlang节点不包含节点所在机器的域名,如果使用name就需要指定域名,比如: 127.0.0.1  zen.com

Windows 下c:\Windows\System32\drivers\etc\hosts

Centos 路径 /etc/hosts

  

[3] 如果在一台机器上启动多个节点,就需要用端口号和节点名称区分开,即使在多个机器上部署一般我们也会避免使用RabbitMQ的默认端口.这里也有很多方式,最快捷的方式就是添加变量启动节点,在生产环境肯定需要使用配置文件来实现.下面是我测试使用的一组节点启动命令:

复制代码
RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detached

RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detached

RABBITMQ_NODE_PORT=9993 RABBITMQ_NODENAME=z_93@zen.com ./rabbitmq-server -detached

RABBITMQ_NODE_PORT=9994 RABBITMQ_NODENAME=z_94@zen.com ./rabbitmq-server -detached
复制代码

 

[4] 如果是在多台物理机进行测试,那么注意打开4369端口,保证EPMD正常工作.这个也可以通过修改环境变量ERL_EPMD_PORT使用别的端口.

 

[5] 执行命令细心一点,特别是关闭应用程序是stop_app,如果你执行的是stop,整个节点都会关闭,后续操作就错了;

   有一些操作过程不需要执行reset,这里也要注意,想清楚自己要做什么再动手.

 

  下面我们走一个step by step的过程,完成一些RabbitMQ集群组建的常见的操作

Just do it

 

从零开始创建集群 

 

  1. 启动z_91@zen.com节点
  2. 启动z_92@zen.com节点
  3. 关闭z_91节点的应用程序  ./rabbitmq-util -n z_91@zen.com stop_app
  4. 重置节点配置和元数据(可以理解为恢复出厂设置)  ./rabbitmq-util -n z_91@zen.com reset
  5. 91与92节点组成集群  ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com
  6. 启动91节点  ./rabbitmq-util -n z_91@zen.com start_app
  7. 查看集群的状态  ./rabbitmq-util -n z_91@zen.com cluster_status
复制代码
[root@localhost scripts]#
[root@localhost scripts]# RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]# RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop_app
Stopping node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com reset
Resetting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com
Clustering node 'z_91@zen.com' with ['z_92@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com start_app
Starting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_92@zen.com']},{ram,['z_91@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
复制代码

   细心的你一定发现了,这里的结果有点奇怪,91节点将92节点拉入组成集群,但是disc节点是92,91节点是ram节点!这是怎么回事?我们暂且按下不表,后面细说,先来把实验做完.

  

退出集群

 

  记得911的一部纪录片提到劫机的匪徒在学习开飞机的课程只学习了起飞,没有学习降落,这,,,,,这就是找死去的啊.

  我们能够将Erlang 节点加入集群,也要学会退出集群.  看一下详细的步骤:

  1. 关闭91节点的应用程序 ./rabbitmq-util -n z_91@zen.com stop_app
  2. 重置节点配置和元数据  ./rabbitmq-util -n z_91@zen.com reset
  3. 启动91应用程序   ./rabbitmq-util -n z_91@zen.com start_app
  4. 查看集群状态  ./rabbitmq-util -n z_92@zen.com cluster_status       
复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop_app
Stopping node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com reset
Resetting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com start_app
Starting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster_status                                      
Cluster status of node 'z_92@zen.com' ...
[{nodes,[{disc,['z_92@zen.com']}]},{running_nodes,['z_92@zen.com']}]
...done.
复制代码

   可以看到集群中已经没有91节点了.

 

换一种方式组建集群

 

   下面换一种方式组建集群,目的是观察rabbitmq在构建集群是如何选择Disc node的.和第一种组建方式的差异在于这行命令: ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com z_91@zen.com    这样完成组建之后,查看一下集群状态,注意disk node的已经变成了:   [{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},{running_nodes,['z_92@zen.com','z_91@zen.com']}]

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop_app     
Stopping node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com reset
Resetting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com z_91@zen.com
Clustering node 'z_91@zen.com' with ['z_92@zen.com','z_91@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com start_app
Starting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster_status
Cluster status of node 'z_92@zen.com' ...
[{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},
{running_nodes,['z_91@zen.com','z_92@zen.com']}]
...done.
[root@localhost scripts]# 
复制代码

 

节点类型转换--将92从disk node转为ram node

 

   上面组建的rabbitmq集群里面有两个节点91 92,这两个节点都是disk节点,我们希望可以动态调整节点的类型,比如把92节点从disk node 转成ram node.看一下操作步骤 

  1. 停止92的应用程序   ./rabbitmq-util -n z_92@zen.com stop_app
  2. 重新进行cluster     ./rabbitmq-util -n z_92@zen.com cluster z_91@zen.com
  3. 启动92应用程序   ./rabbitmq-util -n z_92@zen.com start_app       
  4. 查看集群状态     ./rabbitmq-util -n z_92@zen.com cluster_status

  通过查看集群状态,可以看到92已经变成了Ram节点.注意:在停止了92的应用程序之后并没有执行reset操作.

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com stop_app
Stopping node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster z_91@zen.com
Clustering node 'z_92@zen.com' with ['z_91@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com start_app          
Starting node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster_status
Cluster status of node 'z_92@zen.com' ...
[{nodes,[{disc,['z_91@zen.com']},{ram,['z_92@zen.com']}]},
{running_nodes,['z_91@zen.com','z_92@zen.com']}]
...done.
[root@localhost scripts]# 
复制代码

  

节点类型转换--将92修改为disk节点

 

   上面的过程将92从disk node转换成为ram node ,下面我们执行逆过程,将92再转成disk node,看下过程:

  1. 关闭92应用程序   ./rabbitmq-util -n z_92@zen.com stop_app
  2. 重新执行Cluster  ./rabbitmq-util -n z_92@zen.com cluster z_91@zen.com z_92@zen.com
  3. 启动92应用程序   ./rabbitmq-util -n z_92@zen.com start_app
  4. 检查集群状态      ./rabbitmq-util -n z_91@zen.com cluster_status
  这里的要点就是在cluster命令,./rabbitmq-util -n z_92@zen.com cluster z_91@zen.com z_92@zen.com 当92执行cluster包含自己的时候,就会把自己设置为disk node.
 
复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status                                  
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_91@zen.com']},{ram,['z_92@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com stop_app
Stopping node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster z_91@zen.com z_92@zen.com
Clustering node 'z_92@zen.com' with ['z_91@zen.com','z_92@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com start_app
Starting node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
[root@localhost scripts]# 
复制代码

  

增加node 93

 

   在上面的基础上我们新增一个节点93:

复制代码
[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com cluster_status
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_93@zen.com']}]},{running_nodes,['z_93@zen.com']}]
...done.
[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com stop_app
Stopping node 'z_93@zen.com' ...
...done.
[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com reset
Resetting node 'z_93@zen.com' ...
...done.

[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com cluster z_91@zen.com z_92@zen.com      
Clustering node 'z_93@zen.com' with ['z_91@zen.com','z_92@zen.com'] ...
...done.
[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com start_app
Starting node 'z_93@zen.com' ...
...done.
[root@localhost scripts]# ./rabbitmq-util -n z_93@zen.com cluster_status
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},{ram,['z_93@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com','z_93@zen.com']}]
...done.
复制代码

 

  重新启动节点,我们首先启动节点RAM节点93 

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop
Stopping and halting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com stop
Stopping and halting node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com stop
Stopping and halting node 'z_93@zen.com' ...
...done.
[root@localhost scripts]# RABBITMQ_NODE_PORT=9993 RABBITMQ_NODENAME=z_93@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com cluster_status
Cluster status of node 'z_93@zen.com' ...
Error: unable to connect to node 'z_93@zen.com': nodedown
复制代码

 

  启动93失败了,这是因为93节点是RAM节点并没有持久化集群的元数据,启动时需要连接到disk node获取集群元数据,而这时其它的节点都没有启动,所以启动就失败了.下面我们尝试先启动92节点:

复制代码
[root@localhost scripts]# RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster_status                                   
Cluster status of node 'z_92@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},{ram,['z_93@zen.com']}]},
{running_nodes,['z_92@zen.com']}]
...done.
复制代码

 

  是正常的,下面我们启动93节点

复制代码
[root@localhost scripts]# RABBITMQ_NODE_PORT=9993 RABBITMQ_NODENAME=z_93@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com cluster_status                                   
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},{ram,['z_93@zen.com']}]},
{running_nodes,['z_92@zen.com','z_93@zen.com']}]
...done.
复制代码

 

 乘胜追击,继续启动91节点,注意cluster_status里面running nodes的变化:

复制代码
[root@localhost scripts]# RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com cluster_status                                  
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},{ram,['z_93@zen.com']}]},
{running_nodes,['z_91@zen.com','z_92@zen.com','z_93@zen.com']}]
...done.
[root@localhost scripts]# 
复制代码

 

发布消息到集群

 

   我们用C#写一段代码连接到92节点 创建队列,并发布两条消息;可以看到消息虽然连接到92节点,集群中的其它节点也都有了队列信息.

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com list_queues
Listing queues ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com list_queues
Listing queues ...
zen_qp_pic_queue        1
qp_pic_queue2   1
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com list_queues 
Listing queues ...
zen_qp_pic_queue        1
qp_pic_queue2   1
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com list_queues
Listing queues ...
zen_qp_pic_queue        1
qp_pic_queue2   1
...done.
[root@localhost scripts]#
复制代码

 

  在没有disk node的情况下,添加节点,移除节点

 

 为了方便下面的实验,我们添加94节点到集群中,过程省略,我们检查一下集群状态:

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_94@zen.com cluster_status
Cluster status of node 'z_94@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},
         {ram,['z_94@zen.com','z_93@zen.com']}]},
{running_nodes,['z_92@zen.com','z_93@zen.com','z_91@zen.com',
                 'z_94@zen.com']}]
...done.
复制代码

 

 现在集群中两个disk node: 91 92 两个RAM Node:93 94 

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop
Stopping and halting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com stop
Stopping and halting node 'z_92@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com cluster_status
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},
         {ram,['z_94@zen.com','z_93@zen.com']}]},
{running_nodes,['z_94@zen.com','z_93@zen.com']}]
...done.
[root@localhost scripts]#
复制代码

 

下面我们新增一个节点到集群中(过程略),看下结果

[root@localhost scripts]#  ./rabbitmq-util -n z_95@zen.com cluster_status
Cluster status of node 'z_95@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},
         {ram,['z_95@zen.com','z_94@zen.com','z_93@zen.com']}]},
{running_nodes,['z_94@zen.com','z_93@zen.com','z_95@zen.com']}]
...done.

 

  现在我们把集群中的所有节点都关闭,然后再启动,看下会是什么情况:

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_95@zen.com stop
Stopping and halting node 'z_95@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_94@zen.com stop
Stopping and halting node 'z_94@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com stop
Stopping and halting node 'z_93@zen.com' ...
...done.
复制代码

 

启动集群中所有的节点

复制代码
[root@localhost scripts]# RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},
         {ram,['z_94@zen.com','z_93@zen.com']}]},
{running_nodes,['z_91@zen.com']}]
...done.
复制代码
复制代码
[root@localhost scripts]# RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]# RABBITMQ_NODE_PORT=9993 RABBITMQ_NODENAME=z_93@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]# RABBITMQ_NODE_PORT=9994 RABBITMQ_NODENAME=z_94@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_93@zen.com cluster_status                                   
Cluster status of node 'z_93@zen.com' ...
[{nodes,[{disc,['z_92@zen.com','z_91@zen.com']},
         {ram,['z_94@zen.com','z_93@zen.com']}]},
{running_nodes,['z_94@zen.com','z_92@zen.com','z_93@zen.com']}]
...done.
复制代码

     这时都是正常的,但是如果我们把95节点也启动,就会出现异常,91 92 节点可能会当掉.后面再启动就变成非常混乱的局面了.同样,如果在没有disk node的情况下移除了节点,也会导致这种混乱,甚至会导致disk node无法正常启动,必须把节点重新加入之后,disk node才可以正常启动.

 

   在disk node全部关闭的情况下,我们可以继续使用集群,就像什么都没有发生一样,但是使用过程中声明的新的exchange queues等都会随着节点的重启烟消云散.

 

有可能遇到的问题

 

  问题1 怎样从头再来?

 

          如果你测试过程中把节点关系搞得乱七八糟,各种重启都会失败,想从头再来,但是崩溃的是reset命令执行也是失败;没有关系,要Hold住,转到/var/lib/rabbitmq/mnesia  目录把出问题节点对应的文件删掉,重启即可.

 

  问题2 "Incompatible schema cookies. Please, restart from old backup"

 

   在组建RabbitMQ集群的过程中,你可能会遇到"Incompatible schema cookies. Please, restart from old backup"的问题,这往往是下面的原因造成的:cluster多个节点,而这些节点并没有构成集群.复现一下这个错误:我们启动95 96 97 三个独立的节点,然后 ./rabbitmq-util -n z_97@zen.com cluster z_95@zen.com z_96@zen.com 注意这时95 96并没有组成集群,发生了上面的"Incompatible schema cookies. Please, restart from old backup"异常. 

 往往着急看到效果的时候,会犯这样的错,在不熟练的时候循序渐进的练习一下是很有必要的,可以避开一些坑.

 

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_95@zen.com cluster_status
Cluster status of node 'z_95@zen.com' ...
[{nodes,[{disc,['z_95@zen.com']}]},{running_nodes,['z_95@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_96@zen.com cluster_status
Cluster status of node 'z_96@zen.com' ...
[{nodes,[{disc,['z_96@zen.com']}]},{running_nodes,['z_96@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_97@zen.com cluster_status                                   
Cluster status of node 'z_97@zen.com' ...
[{nodes,[{disc,['z_97@zen.com']}]},{running_nodes,['z_97@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_97@zen.com stop_app
Stopping node 'z_97@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_97@zen.com cluster z_95@zen.com z_96@zen.com
Clustering node 'z_97@zen.com' with ['z_95@zen.com','z_96@zen.com'] ...
Error: {unable_to_join_cluster,
           ['z_95@zen.com','z_96@zen.com'],
           {merge_schema_failed,
               "Incompatible schema cookies. Please, restart from old backup.'z_95@zen.com' = [{name,schema},{type,set},{ram_copies,[]},{disc_copies,['z_95@zen.com']},{disc_only_copies,[]},{load_order,0},{access_mode,read_write},{majority,false},{index,[]},{snmp,[]},{local_content,false},{record_name,schema},{attributes,[table,cstruct]},{user_properties,[]},{frag_properties,[]},{storage_properties,[]},{cookie,{{1352,726635,757709},'z_95@zen.com'}},{version,{{3,0},{'z_95@zen.com',{1352,727291,753066}}}}], 'z_97@zen.com' = [{name,schema},{type,set},{ram_copies,['z_97@zen.com']},{disc_copies,['z_96@zen.com']},{disc_only_copies,[]},{load_order,0},{access_mode,read_write},{majority,false},{index,[]},{snmp,[]},{local_content,false},{record_name,schema},{attributes,[table,cstruct]},{user_properties,[]},{frag_properties,[]},{storage_properties,[]},{cookie,{{1352,727184,282322},'z_96@zen.com'}},{version,{{3,0},{'z_97@zen.com',{1352,727291,780429}}}}]\n"}}
[root@localhost scripts]# 
复制代码

 注:  Rabbitmq 上有人遇到相同的问题 [链接]

 

   通过上面的动手实验,我们已经可以创建和管理RabbitMQ Cluster,但是创建RAM节点还是Disc节点呢?如何做这个选择呢?咱们下回再说

 

   附RabbitMQ Cluster 文档: http://www.rabbitmq.com/clustering.html#auto-config

 

另外,在测试过程中往往在单机创建多个实例,下面的命令常用:

A cluster on a single machine

Under some circumstances it can be useful to run a cluster of RabbitMQ nodes on a single machine. This would typically be useful for experimenting with clustering on a desktop or laptop without the overhead of starting several virtual machines for the cluster. The two main requirements for running more than one node on a single machine are that each node should have a unique name and bind to a unique port / IP address combination for each protocol in use.

You can start multiple nodes on the same host manually by repeated invocation of rabbitmq-server (rabbitmq-server.bat on Windows). You must ensure that for each invocation you set the environment variables RABBITMQ_NODENAME and RABBITMQ_NODE_PORT to suitable values.

For example:

$ RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit rabbitmq-server -detached
$ RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=hare rabbitmq-server -detached
$ rabbitmqctl -n hare stop_app
$ rabbitmqctl -n hare join_cluster rabbit@`hostname -s`
$ rabbitmqctl -n hare start_app

will set up a two node cluster with one disc node and one ram node. Note that if you have RabbitMQ opening any ports other than AMQP, you'll need to configure those not to clash as well - for example:

$ RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15672}]" RABBITMQ_NODENAME=rabbit rabbitmq-server -detached
$ RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=hare rabbitmq-server -detached

will start two nodes (which can then be clustered) when the management plugin is installed.

 

 

最后,小图一张 Maggie Q 简称MQ 我们俩都姓李 Nikita!

 

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
2月前
|
消息中间件 存储 运维
2024最全RabbitMQ集群方案汇总
本文梳理了RabbitMQ集群的几种方案,主要包括普通集群、镜像集群(高可用)、Quorum队列(仲裁队列)、Streams集群模式(高可用+负载均衡)和插件方式。重点介绍了每种方案的特点、优缺点及适用场景。搭建步骤包括安装Erlang和RabbitMQ、配置集群节点、修改hosts文件、配置Erlang Cookie、启动独立节点并创建集群,以及配置镜像队列以提高可用性和容错性。推荐使用Quorum队列与Streams模式,其中Quorum队列适合高可用集群,Streams模式则同时支持高可用和负载均衡。此外,还有Shovel和Federation插件可用于特定场景下的集群搭建。
306 2
|
2月前
|
消息中间件 RocketMQ
2024最全RocketMQ集群方案汇总
在研究RocketMQ集群方案时,发现网上存在诸多不一致之处,如组件包含NameServer、Broker、Proxy等。通过查阅官方文档,了解到v4.x和v5.x版本的差异。v4.x部署模式包括单主、多主、多主多从(异步复制、同步双写),而v5.x新增Local与Cluster模式,主要区别在于Broker和Proxy是否同进程部署。Local模式适合平滑升级,Cluster模式适合高可用需求。不同模式下,集群部署方案大致相同,涵盖单主、多主、多主多从等模式,以满足不同的高可用性和性能需求。
295 0
|
6月前
|
消息中间件 存储 负载均衡
|
6月前
|
消息中间件 存储 负载均衡
"RabbitMQ集群大揭秘!让你的消息传递系统秒变超级英雄,轻松应对亿级并发挑战!"
【8月更文挑战第24天】RabbitMQ是一款基于AMQP的开源消息中间件,以其高可靠性、扩展性和易用性闻名。面对高并发和大数据挑战时,可通过构建集群提升性能。本文深入探讨RabbitMQ集群配置、工作原理,并提供示例代码。集群由多个通过网络连接的节点组成,共享消息队列,确保高可用性和负载均衡。搭建集群需准备多台服务器,安装Erlang和RabbitMQ,并确保节点间通信顺畅。核心步骤包括配置.erlang.cookie文件、使用rabbitmqctl命令加入集群。消息发布至任一节点时,通过集群机制同步至其他节点;消费者可从任一节点获取消息。
71 2
|
6月前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
133 0
|
7月前
|
消息中间件 Prometheus 监控
消息队列 MQ使用问题之如何将旧集群的store目录迁移到新集群
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
7月前
|
消息中间件 RocketMQ
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
|
6月前
|
消息中间件 API 数据安全/隐私保护
就软件研发问题之RocketMQ ACL 2.0加强集群组件间访问控制的问题如何解决
就软件研发问题之RocketMQ ACL 2.0加强集群组件间访问控制的问题如何解决
|
7月前
|
消息中间件 负载均衡 算法
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
210 2
|
7月前
|
消息中间件 存储 Java
【RocketMQ 系列三】RocketMQ集群搭建(2m-2s-sync)
【RocketMQ 系列三】RocketMQ集群搭建(2m-2s-sync)
490 1