整体架构
RabbitMQ Cluster 架构图
部署步骤基于 Docker
- 基本概念
- 内存节点
只保存状态到内存,例外情况是:持久的 queue 的内容将被保存到磁盘。 - 磁盘节点
保存状态到内存和磁盘。 - 内存节点由于不进行磁盘读写,它的性能比磁盘节点高。
- 集群中可以存在多个磁盘节点,磁盘节点越多整个集群可用性越好,但是集群整体性能不会线性增加,需要权衡考虑。
- 如果集群中只有内存节点,那么不能停止它们,否则所有状态和消息都会丢失。
2. 安装 RabbitMQ
- 准备四台主机,我是用 Docker 来创建的,命令如下:
- 选择一个合适的版本下载 ,下载地址:Downloading and Installing RabbitMQ
- 下面是每一步的命令:
在 rabbitmq2 和 rabbitmq3 同样执行上面的步骤即可。
- 运行 Rabbitmq
现在 RabbitMQ 就已经启动起来了,但是有一个问题,RabbitMQ 一直占据着终端,我们得让它在后台运行。Ctrl+C 终止进程,然后执行命令
可以使用命令查看运行状态:
root@rabbitmq1:~/rabbitmq_server-3.6.14/sbin# ./rabbitmqctl status
下面开始将这三个独立的 RabbitMQ 组建成一个集群。
- Rabbit 集群
- 集群模式
集群中的节点有两种,一种是内存节点,一种是磁盘节点;内存节点由于没有磁盘读写,性能比磁盘节点要好,磁盘节点可以将状态持久化到磁盘,可用性比内存节点要好,需要权衡考虑。 本文的模式是一台磁盘节点,作为数据备份,两台内存节点,用于提高性能。 - 配置 hosts
在安装好 RabbitMQ 的三台机器上分别修改 /etc/hosts 文件。
rabbit@rabbitmq1 上:
rabbit@rabbitmq2 上:
rabbit@rabbitmq3 上:
- 配置 Cookie
为了保证这三台机器的 Erlang cookie 相同,我们将 rabbitmq1 上面的 Erlang cookie 文件复制到另外两台机器上面。在我的机器上面, Erlang cookie 文件的路径是/root/.erlang.cookie
,下面是将这个 cookie 文件复制到另外两台机器上的步骤:(在 Docker 宿主机上执行)
步骤解释:现将 rabbitmq1 上的 .erlang.cookie 复制到宿主机的当前目录,然后在分别复制到 rabbitmq2 和 rabbitmq3 上的 root 目录下。
OK,现在三台机器上具有相同的 Erlang cookie 了。下面开始组建集群。
- 查看集群状态
可以看到 {cluster_name,<<"rabbit@rabbitmq1">>}
,这是集群名字,其他节点可以 join
到这个集群中。
其实,所有节点都是平等的,你可以加入到任意一个集群中,最终这些节点都会在同一个集群中。
- 将 RabbitMQ 停止运行
rabbitmq2:
rabbitmq3:
- 执行加入集群命令
rabbitmq2:
rabbitmq3:
在任意节点查看集群状态:
可以看到三个节点已经构建成了一个集群,但是有一个小问题,{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}
,所有的节点都是磁盘节点,和刚开始构想的不太一样,我们只需要一个磁盘节点,另外两个都是内存节点,这样我们在保证可用性的同时,还能提高集群的整体性能。
所以,我们需要将两台磁盘节点改成内存节点。
- 将节点从集群中移除
rabbitmq2:
rabbitmq3:
这里关键的命令是 ./rabbitmqctl reset
。reset 命令在节点为单机状态和是集群的一部分时行为有点不太一样。
节点单机状态时,reset 命令将清空节点的状态,并将其恢复到空白状态。当节点是集群的一部分时,该命令也会和集群中的磁盘节点通信,告诉他们该节点正在离开集群。
这很重要,不然,集群会认为该节点出了故障,并期望其最终能够恢复回来,在该节点回来之前,集群禁止新的节点加入。
- 将节点重新加入集群
rabbitmq2:
rabbitmq3:
然后查看集群状态:
现在集群已经大体符合开始时我们的构想了,一个磁盘节点,两个内存节点。但是,我们的集群还是有点小问题,我们这个集群更适合非持久化队列,只有该队列是非持久的,客户端磁能重新连接到集群里的其他节点,并创建队列。加入该队列是持久化的,那么我们将集群恢复的唯一办法是将故障节点恢复起来。所以,我们需要对我们的集群进行改造,稍后我们会看到 Rabbit 团队给我们带来的内建的双活冗余选项:镜像队列。
- 使用 HAProxy 做负载均衡
- 下载 HAProxy 源码
Git 仓库地址:Git: haproxy
下载源码:
- 编译&安装
更详细的编译参数请参考文档,本文通用的编译参数。
编译 & 安装:
现在你可以运行 haproxy --help
来看看它的配置选项。现在需要对 HAProxy 进行配置,这样它就可以 RabbitMQ 做负载均衡了。
- 配置 HAProxy
HAProxy 使用单一配置文件来定义所有属性,包括从前端 IP 到后端服务器。下列清单展示了用于本地 Rabbit 集群负载均衡的配置。
配置文件参数解释:
我们的配置文件(/root/haproxy/haproxy.cnf)内容如下:
- 运行 HAProxy
让我们用新的配置启动 HAProxy 并确保它能工作:
如果一切正常的话,你现在可以顺利的加载 http://localhost:8100/stats
页面,如果配置文件中配置了 auth
的话,你需要进行登录:
WX20171110-154612@2x.png
这有个小缺陷,虽然我们在配置文件中做了 management 的反向代理,但是我们仍然不能访问 http://localhost:8102/
。这是因为我们没有开启 rabbit management 插件,下面我们来开启这个插件。
- 开启 Rabbit Management 插件,从 WEB 端管理 RabbitMQ
插件是一种扩展作者未能预见到的服务器的行为方式。RabbitMQ 插件是由 Erlang 语言编写的,并且和服务器一同运行在同一个 Erlang VM 中。我们先开启 Management 插件。执行如下命令:
然后重新访问 http://localhost:8102/
,页面提示我们需要登录,RabbitMQ 有一个默认的账号 guest,密码是 guest。我们用这个账号登陆会发现,我们被拒绝了,页面提示 User can only log in via localhost
,这是因为rabbitmq从3.3.0开始禁止使用guest/guest权限通过除localhost外的访问。如果想使用 guest 通过远程机器访问,需要在 RabbitMQ 配置文件中设置 loopback_users 为 [],我们的配置文件内容如下:/root/rabbitmq_server-3.6.14/etc/rabbitmq/rabbitmq.config :
刷新页面,然后重新登陆,现在我们能看到如下的界面:
WechatIMG84.jpeg
下面黄色部分是因为另外两个节点还未开启 Management 插件,开启即可。
- 使用 RabbitMQ 镜像功能(待补充)
- 关闭生产者
- 备份当前配置
- 排空队列 - 观察队列状态,直到所有队列都为空
- 关闭节点
- 解压新版本 RabbitMQ 到现有的安装目录
- 启动磁盘节点
- 启动内存节点
以上内容希望帮助到大家