本文共 3276 字,大约阅读时间需要 10 分钟。
刚开始使用rabbitmqctl 创建集群的时候会有一个问题,怎么控制节点是disk node还是ram node?翻看了rabbitmq2.8.7的代码看了一下才知道原委,记录一下:
这个实验其实之前已经做过了,这里抽出来做对比:
[root@localhost scripts]#[root@localhost scripts]# RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detachedActivating RabbitMQ plugins ...0 plugins activated:[root@localhost scripts]# RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detachedActivating RabbitMQ plugins ...0 plugins activated:[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com stop_appStopping node 'z_91@zen.com' ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com resetResetting node 'z_91@zen.com' ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.comClustering node 'z_91@zen.com' with ['z_92@zen.com'] ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com start_appStarting node 'z_91@zen.com' ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com cluster_statusCluster 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节点!这是怎么回事?下面换一种方式组建集群,目的是观察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 resetResetting node 'z_91@zen.com' ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com z_91@zen.comClustering 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_appStarting node 'z_91@zen.com' ......done.[root@localhost scripts]# ./rabbitmq-util -n z_91@zen.com cluster_statusCluster 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_statusCluster 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]#
我们先把答案说了,这是因为方法should_be_disc_node
should_be_disc_node(ClusterNodes) -> ClusterNodes == [] orelse lists:member(node(), ClusterNodes).
当集群初建的时候,没有节点是disk node,ClusterNodes为[]所以会把加入集群的第一个新节点设置为disk node;当ClusterNodes不为空的时候,只要ClusterNodes包含当前节点,就会把当前节点设置为disk node;ClusterNodes就是来自于rabbitmqctl cluster命令后跟的参数.
下面是详细的代码跟进过程,不再赘述,代码里面对一些关键的地方加了补充说明,比较容易理解.
rabbitmqctl的实现逻辑实际上是在rabbitcontrol模块,我们关注的是action(cluster...)分支:
..\rabbitmq-server-2.8.7\src\rabbit_control.erlaction(cluster, Node, ClusterNodeSs, _Opts, Inform) -> ClusterNodes = lists:map(fun list_to_atom/1, ClusterNodeSs), Inform("Clustering node ~p with ~p", [Node, ClusterNodes]), rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes]);
rabbitcontrol 调用的是rabbit_mnesia的cluster方法,跟进去看:
代码太长了,展开看吧 : )
最后,小图一张 我有一个一样的台灯
转载地址:http://yheql.baihongyu.com/