目的
验证 nodes 和 exactly 两种镜像方式的特性,测试内容为:
- 搭建 nodes 方式的镜像。
- 搭建 exactly 方式的镜像。
- 利用命令行查看镜像状态。
- 删除镜像。
- 在采用 exactly 方式下,对比含有镜像队列的节点 down 机后是否会有新的镜像节点产生新队列镜像。
环境
实验室环境的 3 台 Rabbit MQ 服务器,已经配置好集群。
过程
针对现有的队列增加 1 个类型为 nodes 的镜像
-
使用 cluster_status 命令查看集群状态是否正常
$ rabbitmqctl cluster_status
Cluster status of node 'rabbit@TK-RABBITMQ2' ...
[{nodes,[{disc,['rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2','rabbit@TK-RABBITMQ3']}]},
{running_nodes,['rabbit@TK-RABBITMQ3','rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2']},
{cluster_name,<<"rabbit@TK-RABBITMQ1">>},
{partitions,[]},
{alarms,[{'rabbit@TK-RABBITMQ3',[]},{'rabbit@TK-RABBITMQ1',[]},{'rabbit@TK-RABBITMQ2',[]}]}
输出内容的大致意思是:
- nodes:所有节点列表;
- disc:指磁盘节点;
- running_nodes:正在运行的节点;
- cluster_name:集群名称,这个集群没有定义过名称,就用系统默认的了;
- patitions:系统侦测到的网络分裂;
- alarms:每个节点上的警告。
2. 建立一个名为 test_policy 的策略,内容为:名称为 “test.” 开头的队列,镜像到集群里面的TK-RABBITMQ2节点。
$ rabbitmqctl set_policy test_policy "^test\." '{"ha-mode":"nodes","ha-params":["rabbit@TK-RABBITMQ2"]}'
Setting policy "test_policy" for pattern "^test\\." to "{\"ha-mode\":\"test\",\"ha-params\":[\"rabbit@TK-RABBITMQ2\"]}" with priority "0" ...
3. 查看集群环境下的策略
$ rabbitmqctl list_policies
Setting policy "test_policy" for pattern "^test\\." to "{\"ha-mode\":\"test\",\"ha-params\":[\"rabbit@TK-RABBITMQ2\"]}" with priority "0" ...
4. 查看被同步的队列信息
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ1.1.27447.16> [<rabbit@TK-RABBITMQ2.1.5939.0>]
test.222 test_policy <rabbit@TK-RABBITMQ1.1.27574.16> [<rabbit@TK-RABBITMQ2.1.5936.0>]
hello_111 <rabbit@TK-RABBITMQ1.1.20324.17>
test_222 <rabbit@TK-RABBITMQ1.1.27681.16>
test_333 <rabbit@TK-RABBITMQ1.1.20657.17>
hello <rabbit@TK-RABBITMQ1.1.30177.16>
hello_444 <rabbit@TK-RABBITMQ1.1.21373.17>
test_111 <rabbit@TK-RABBITMQ1.1.27319.16>
此时可以看到 test.111 和 test.222 两个队列已经应用了 test_policy 策略。
5. kill 掉TK-RABBITMQ2节点,在其它节点上查看策略信息和同步的队列信息
$ rabbitmqctl list_policies
Listing policies ...
/ test_policy all ^ {"ha-mode":"nodes","ha-params":["rabbit@TK-RABBITMQ2"]} 0
策略是在 TK-RABBITMQ2 节点上建立的,但是 kill 掉此节点后,策略依旧可以在其它节点上被查询到,说明策略是应用在集群上的,不会因为建立策略的节点关闭而失效。
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ1.1.27447.16> []
test.222 test_policy <rabbit@TK-RABBITMQ1.1.27574.16> []
hello_111 <rabbit@TK-RABBITMQ1.1.20324.17>
test_222 <rabbit@TK-RABBITMQ1.1.27681.16>
test_333 <rabbit@TK-RABBITMQ1.1.20657.17>
hello <rabbit@TK-RABBITMQ1.1.30177.16>
hello_444 <rabbit@TK-RABBITMQ1.1.21373.17>
test_111 <rabbit@TK-RABBITMQ1.1.27319.16>
因为 test.111 和 test.222 两个队列只在 TK-RABBITMQ2 节点上有镜像,所以当 TK-RABBITMQ2 节点关闭后,镜像节点消失,但队列没有消失。
6. 使用 detached 命令重启节点,删除镜像,再查看镜像信息
$ rabbitmqctl clear_policy test_policy
Clearing policy "test_policy" ...
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 <rabbit@TK-RABBITMQ1.1.27447.16>
test.222 <rabbit@TK-RABBITMQ1.1.27574.16>
hello_111 <rabbit@TK-RABBITMQ1.1.20324.17>
test_222 <rabbit@TK-RABBITMQ1.1.27681.16>
test_333 <rabbit@TK-RABBITMQ1.1.20657.17>
hello <rabbit@TK-RABBITMQ1.1.30177.16>
hello_444 <rabbit@TK-RABBITMQ1.1.21373.17>
test_111 <rabbit@TK-RABBITMQ1.1.27319.16>
针对现有的队列增加 2 个类型为 nodes 的镜像
1. 使用 cluster_status 命令查看集群状态是否正常
$ rabbitmqctl cluster_status
Cluster status of node 'rabbit@TK-RABBITMQ2' ...
[{nodes,[{disc,['rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2','rabbit@TK-RABBITMQ3']}]},
{running_nodes,['rabbit@TK-RABBITMQ3','rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2']},
{cluster_name,<<"rabbit@TK-RABBITMQ1">>},
{partitions,[]},
{alarms,[{'rabbit@TK-RABBITMQ3',[]},{'rabbit@TK-RABBITMQ1',[]},{'rabbit@TK-RABBITMQ2',[]}]}
2. 建立一个名为 test_policy 的策略,内容为:名称为 “test.” 开头的队列,镜像到集群里面的 TK-RABBITMQ2 和 TK-RABBITMQ3 节点。
$ rabbitmqctl set_policy test_policy "^test\." '{"ha-mode":"nodes","ha-params":["rabbit@TK-RABBITMQ2","rabbit@TK-RABBITMQ3"]}'
Setting policy "test_policy" for pattern "^test\\." to "{\"ha-mode\":\"nodes\",\"ha-params\":[\"rabbit@TK-RABBITMQ2\",\"rabbit@TK-RABBITMQ3\"]}" with priority "0" ...
3. 查看集群环境下的策略
$ rabbitmqctl list_policies
Listing policies ...
/ test_policy all ^test\\. {"ha-mode":"nodes","ha-params":["rabbit@TK-RABBITMQ2","rabbit@TK-RABBITMQ3"]} 0
4. 查看被同步的队列信息
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ1.1.27447.16> [<rabbit@TK-RABBITMQ2.3.10285.20>, <rabbit@TK-RABBITMQ3.2.24951.140>]
test.222 test_policy <rabbit@TK-RABBITMQ1.1.27574.16> [<rabbit@TK-RABBITMQ2.3.10289.20>, <rabbit@TK-RABBITMQ3.2.24970.140>]
test_222 <rabbit@TK-RABBITMQ1.1.27681.16>
hello <rabbit@TK-RABBITMQ1.1.30177.16>
test_111 <rabbit@TK-RABBITMQ1.1.27319.16>
5. kill 掉 TK-RABBITMQ2 节点,查看被同步的队列信息
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ1.1.27447.16> [<rabbit@TK-RABBITMQ3.2.24951.140>]
test.222 test_policy <rabbit@TK-RABBITMQ1.1.27574.16> [<rabbit@TK-RABBITMQ3.2.24970.140>]
test_222 <rabbit@TK-RABBITMQ1.1.27681.16>
hello <rabbit@TK-RABBITMQ1.1.30177.16>
test_111 <rabbit@TK-RABBITMQ1.1.27319.16>
因为 test.111 和 test.222 两个队列在 TK-RABBITMQ2 和 TK-RABBITMQ3节点上有镜像,所以当 TK-RABBITMQ2 节点关闭后,镜像TK-RABBITMQ2节点消失,镜像TK-RABBITMQ3节点依然存在。
搭建 exactly 方式的镜像
1. 使用 cluster_status 命令查看集群状态是否正常
$ rabbitmqctl cluster_status
Cluster status of node 'rabbit@TK-RABBITMQ2' ...
[{nodes,[{disc,['rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2',
'rabbit@TK-RABBITMQ3']}]},
{running_nodes,['rabbit@TK-RABBITMQ3','rabbit@TK-RABBITMQ1',
'rabbit@TK-RABBITMQ2']},
{cluster_name,<<"rabbit@TK-RABBITMQ1">>},
{partitions,[]},
{alarms,[{'rabbit@TK-RABBITMQ3',[]},
{'rabbit@TK-RABBITMQ1',[]},
{'rabbit@TK-RABBITMQ2',[]}]}
2. 建立一个名为 test_policy 的策略,内容为:名称为 “test.” 开头的队列,镜像到集群里面的随机两个节点。
$ rabbitmqctl set_policy test_policy "^test\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
3. 查看集群环境下的策略
$ rabbitmqctl list_policies
Listing policies ...
/ test_policy all ^test\\. {"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"} 0
4. 查看被同步的队列信息
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ1.2.12033.520> [<rabbit@TK-RABBITMQ2.3.23079.1>]
test.222 test_policy <rabbit@TK-RABBITMQ1.2.12190.520> [<rabbit@TK-RABBITMQ3.2.6391.121>]
hello_111 <rabbit@TK-RABBITMQ1.2.25478.518>
test_222 <rabbit@TK-RABBITMQ1.2.19875.518>
test_333 <rabbit@TK-RABBITMQ1.2.24234.518>
hello <rabbit@TK-RABBITMQ3.2.21301.118>
hello_444 <rabbit@TK-RABBITMQ1.2.24432.519>
test_111 <rabbit@TK-RABBITMQ1.2.18296.518>
5. kill 掉TK-RABBITMQ1节点(主节点),查看被同步的队列信息
$ rabbitmqctl list_queues name policy pid slave_pids
Listing queues ...
test.111 test_policy <rabbit@TK-RABBITMQ3.2.9311.145> [<rabbit@TK-RABBITMQ2.3.1852.0>]
test.222 test_policy <rabbit@TK-RABBITMQ3.2.9330.145> [<rabbit@TK-RABBITMQ2.3.1848.0>]
结论
- 没有被镜像的队列,在主节点服务宕机后将丢失
- 使用只有一个节点的 nodes 策略做镜像,有镜像的服务器(不是主服务器)宕机后,消息不会丢失;主服务器(不是有镜像的服务器)宕机后消息也不会丢失
- 使用含有两个节点的 nodes 策略做镜像,有镜像的一台服务器宕机后,消息不会丢失;主服务器宕机后消息也不会丢失
- 使用 exactly 策略镜像到两台服务器,主服务器宕机后队列将按照镜像的规则随机镜像到另外的两台服务器上,消息不会丢失
更多实验可点击:Rabbitmq 实验