第7章 RabbitMQ运维
7.1 集群搭建
在1.4节中,
RabbitMQ集群允许消费者和生产者在RabbitMQ单个节点崩溃的情况下继续运行,
不过RabbitMQ集群不能保证消息的万无一失,
但是不会备份消息(当然通过特殊的配置比如镜像队列可以解决这个问题,
不同于队列那样拥有自己的进程,交换器其实只是一个名称和绑定列表。当消息发布到交换器时,实际上是由所连接的信道将消息上的路由键同交换器的绑定列表进行比较,然后再路由消息。当创建一个新的交换器时,RabbitMQ所要做的就是将绑定列表添加到集群中的所有节点上。这样,每个节点上的信道都可以访问到新的交换器了。
介绍完这些预备知识,
7.1.1 多机多节点配置
多机多节点是针对下一节的单机多节点而言的,主要是指在每台机器中部署一个RabbitMQ服务节点,进而由多台机器组成一个RabbitMQ集群。在配置集群之前,需要根据1.4节的方法正确地安装RabbitMQ。
假设这里一共有三台物理主机,均已正确地安装了RabbitMQ,且主机名分别为node1、node2和node3。RabbitMQ集群对延迟非常敏感,应当只在本地局域网内使用。在广域网中不应该使用集群,而应该使用Federation或Shovel来代替。
接下来需要按照以下步骤执行。
第一步,配置各个节点的hosts文件,让各个节点都能互相识别对方的存在。比如在Linux系统中可以编辑/etc/hosts文件,在其上添加IP地址与节点名称的映射信息:
192.168.0.2 node1
192.168.0.3 node2
192.168.0.4 node3
第二步,编辑RabbitMQ的cookie文件,以确保各个节点的cookid文件使用的是同一个值。可以读取node1节点的cookie值,然后将其复制到node2和node3节点中。cookie文件默认路径为/var/lib/rabbitmq/.erlang.cookie或者$HOME/.erlang.cookie。 cookie相当于密钥令牌,集群中的RabbitMQ节点需要通过交换密钥令牌以获得相互认证。
# node1 拷贝 cookie
[www@RabbitMQ-Node1 ~]$ sudo cat /var/lib/rabbitmq/.erlang.cookie
# node2 复制 cookie
# 增加 .erlang.cookie 文件的写权限
[www@RabbitMQ-Node2 ~]$ sudo chmod u+w /var/lib/rabbitmq/.erlang.cookie
# 编辑 .erlang.cookie 文件,修改 cookie 为 node1 的cookie
[www@RabbitMQ-Node2 ~]$ sudo vim /var/lib/rabbitmq/.erlang.cookie
# 恢复 .erlang.cookie 文件的只读权限
[www@RabbitMQ-Node2 ~]$ sudo chmod u-w /var/lib/rabbitmq/.erlang.cookie
# node3 复制 cookie
# 增加 .erlang.cookie 文件的写权限
[www@RabbitMQ-Node3 ~]$ sudo chmod u+w /var/lib/rabbitmq/.erlang.cookie
# 编辑 .erlang.cookie 文件,修改 cookie 为 node1 的cookie
[www@RabbitMQ-Node3 ~]$ sudo vim /var/lib/rabbitmq/.erlang.cookie
# 恢复 .erlang.cookie 文件的只读权限
[www@RabbitMQ-Node3 ~]$ sudo chmod u-w /var/lib/rabbitmq/.erlang.cookie
第三步,配置集群。配置集群有三种方式:通过 rabbitmqctl 工具配置;通过 rabbitmq.config 配置文件配置;通过 rabbitmq-autocluster 插件配置。这里主要讲的是通过rabbitmqctl工具的方式配置集群,这种方式也是最常用的方式。 其余两种方式在实际应用中用之甚少,所有不多做介绍。
首先启动node1、node2和node3这3个节点的RabbitMQ服务。
[www@RabbitMQ-Node1 ~]$ sudo rabbitmq-server -detached
[www@RabbitMQ-Node2 ~]$ sudo rabbitmq-server -detached
[www@RabbitMQ-Node3 ~]$ sudo rabbitmq-server -detached
这样,这3个节点目前都是以独立节点存在的单个集群。通过 rabbitmqctl cluster_status 命令查看各个节点的状态。
接下来为了讲3个节点组成一个集群,需要以node1节点为基准,将node2和node3节点加入node1节点的集群中。这3个节点是平等的,如果想调换彼此的加入顺序也未尝不可。首先将node2节点加入node1节点的集群中,需要执行如下4个命令步骤。
# 关闭APP
[www@RabbitMQ-Node2 ~]$ sudo rabbitmqctl stop_app
Stopping rabbit application on node rabbit@RabbitMQ-Node2 ...
# 重置APP数据库
[www@RabbitMQ-Node2 ~]$ sudo rabbitmqctl reset
Resetting node rabbit@RabbitMQ-Node2 ...
# 当前节点 node2 加入 node1 节点所在集群
[www@RabbitMQ-Node2 ~]$ sudo rabbitmqctl join_cluster rabbit@Lime-CentOS
Clustering node rabbit@RabbitMQ-Node2 with rabbit@Lime-CentOS
# 启动APP
[www@RabbitMQ-Node2 ~]$ sudo rabbitmqctl start_app
Starting node rabbit@RabbitMQ-Node2 ...
如此,node1节点和node2节点便处于同一个集群之中,我们在这两个节点上都执行 rabbitmqctl cluster_status 命令可以看到同样的输出。
最后将node3节点也加入node1节点所在的集群中,这3个节点组成了一个完整的集群。在任意一个节点中都可以看到如下的集群状态。
Cluster status of node rabbit@RabbitMQ-Node2 ...
Basics
Cluster name: limeRabbitMQ
Disk Nodes
rabbit@Lime-CentOS
rabbit@RabbitMQ-Node2
Running Nodes
rabbit@Lime-CentOS
rabbit@RabbitMQ-Node2
Versions
rabbit@Lime-CentOS: RabbitMQ 3.8.12 on Erlang 23.2.5
rabbit@RabbitMQ-Node2: RabbitMQ 3.8.14 on Erlang 23.2.7
Maintenance status
Node: rabbit@Lime-CentOS, status: not under maintenance
Node: rabbit@RabbitMQ-Node2, status: not under maintenance
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@Lime-CentOS, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@Lime-CentOS, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@Lime-CentOS, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@RabbitMQ-Node2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@RabbitMQ-Node2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Feature flags
Flag: drop_unroutable_metric, state: enabled
Flag: empty_basic_get_metric, state: enabled
Flag: implicit_default_bindings, state: enabled
Flag: maintenance_mode_status, state: enabled
Flag: quorum_queue, state: enabled
Flag: user_limits, state: enabled
Flag: virtual_host_metadata, state: enabled
现在已经完成了集群的搭建。如果集群中某个节点关闭了,那么集群会处于什么样的状态?
这里我们在node2节点上执行 rabbitmqctl stop 命令来主动关闭RabbitMQ应用。。。。
如果关闭了
在重试失败之后,
如果最后一个