RabbitMQ是一个出色的分布式消息代理,但是以编程方式管理起来并不容易。 在本教程中,我将向您展示如何创建集群,添加节点,删除节点,启动和停止。 作为奖励,我将共享一个Fabric文件,让您可以完全控制。 该代码可在GitHub上获得 。
RabbitMQ快速入门
RabbitMQ是一个非常流行的消息队列。 您可以有多个生产者发送消息,而使用者可以完全分离的方式使用这些消息。 RabbitMQ非常受欢迎的原因如下:
- 快速而强大。
- 它是开源的 ,但是如果您需要它可以提供商业支持。
- 它在您的操作系统上运行。
- 它是积极开发的。
- 这是经过战斗考验的。
RabbitMQ在Erlang中实现,这有点不寻常,但这是它如此可靠的原因之一。
先决条件
就本教程而言,我将使用由三个节点组成的本地Vagrant集群。 如果您已经拥有三台可用的计算机(虚拟机或非虚拟机),则可以使用它们。 注意端口和网络。
安装VirtualBox
按照说明安装VirtualBox。
安装无业游民
按照说明安装Vagrant
创建RabbitMQ集群
这是一个Vagrantfile,它将在您的计算机上创建一个本地三节点群集。 操作系统为Ubuntu 14.04(Trusty)。
# -*- mode: ruby -*-
# vi: set ft=ruby :
hosts = {
"rabbit-1" => "192.168.77.10",
"rabbit-2" => "192.168.77.11",
"rabbit-3" => "192.168.77.12"
}
Vagrant.configure("2") do |config|
config.vm.box = "trusty64"
hosts.each_with_index do |(name, ip), i|
rmq_port = 5672 + i
admin_port = 15672 + i
config.vm.define name do |machine|
machine.vm.network :private_network, ip: ip
config.vm.hostname = "rabbit-%d" % [i + 1]
config.vm.network :forwarded_port, guest: 5672, guest_ip: ip, host: rmq_port
config.vm.network :forwarded_port, guest: 15672, guest_ip: ip, host: admin_port
machine.vm.provider "virtualbox" do |v|
v.name = name
end
end
end
end
要创建一个空集群,请输入: vagrant up
。
配置SSH
为了使ssh易于进入群集节点,请输入: vagrant ssh-config >> ~/.ssh/config
。
如果键入: cat ~/.ssh/config
,则应该看到Rabbit-1,rabbit-2和Rabbit-3的条目。
现在,您可以按名称ssh进入每个虚拟机: ssh rabbit-1
。
确保节点可以通过名称到达
最简单的方法是编辑/ etc / hosts文件。 例如,对于rabbit-1,添加rabbit-2和rabbit-3的地址。
192.168.77.11 rabbit-2
192.168.77.12 rabbit-3
对所有节点重复该过程。
安装RabbitMQ
我将在此处将apt-get用于Debian / Ubuntu操作系统。 如果您的集群在其他操作系统上运行,请按照RabbitMQ安装页面上的说明进行操作。
请注意,有时默认情况下会提供过时的RabbitMQ版本。 如果您想安装最新的和最好的,可以按照以下说明直接下载.deb软件包或添加RabbitMQ的apt-repository。
Ubuntu 14.04上RabbitMQ的当前版本是3.2,足以满足我们的目的。 输入以下内容进行自我验证: apt-cache show rabbitmq-server
。
让我们继续将其安装在每台计算机上:
sudo apt-get update
sudo apt-get install rabbitmq-server -y
如果愿意,可以随意使用喜欢的配置管理工具,例如Chef或Ansible。
请注意,必须先安装Erlang 。
启用RabbitMQ管理插件
管理插件真的很棒。 它为您提供了基于HTTP的API以及Web GUI和命令行工具来管理集群。 启用方法如下:
sudo rabbitmq-plugins enable rabbitmq_management
获取管理命令行工具
从http://192.168.77.10:15672/cli/rabbitmqadmin下载。 请注意,RabbitMQ文档不正确,并告诉您从http://下载 :15672 / cli /。
这是RabbitMQ管理HTTP API的基于Python的HTTP客户端。 用脚本编写RabbitMQ集群非常方便。
RabbitMQ基本概念
RabbitMQ实施AMQP 0.9.1标准(高级消息队列协议) 。 请注意,已经存在AMQP 1.0标准,RabbitMQ具有支持它的插件,但由于在现实世界中使用不足,因此被视为原型。
在AMQP模型中,发布者通过交换将消息发送到消息代理(在这种情况下,RabbitMQ是消息代理)。 消息代理基于与消息关联的元数据将消息分发到队列。 使用者使用队列中的消息。 消息可能会或可能不会被确认。 RabbitMQ在这些概念的基础上支持各种编程模型,例如工作队列,发布-订阅和RPC。
管理集群
有三个用于管理集群的脚本。 rabbitmq-server脚本将启动RabbitMQ服务器(启动它)。 Rabbitmqctl用于控制集群(停止,重置,将集群节点放在一起并获取状态)。 您先前下载的rabbitmqadmin用于配置和管理集群(声明虚拟主机,用户,交换和队列)。 创建集群仅涉及rabbitmq-server和rabbitmqctl。
首先,让我们在每个主机rabbit-1,rabbit-2和rabbit-3上启动rabbitmq-server作为服务(守护程序)。
sudo service rabbitmq-server start
如果节点关闭,这将同时启动Erlang VM和RabbitMQ应用程序。 要验证其是否正常运行,请键入:
sudo rabbitmqctl cluster_status
输出应为(对于Rabbit-1):
Cluster status of node 'rabbit@rabbit-1' ...
[{nodes,[{disc,['rabbit@rabbit-1']}]},
{running_nodes,['rabbit@rabbit-1']},
{partitions,[]}]
...done.
这意味着该节点尚未与任何其他节点群集,并且它是一个磁盘节点。 正如您所看到的,它也正在运行,它出现在running_nodes列表中。
要停止服务器,请发出以下命令:
sudo rabbitmqctl stop_app
然后,如果您检查集群状态:
sudo rabbitmqctl cluster_status
输出应为:
Cluster status of node 'rabbit@rabbit-1' ...
[{nodes,[{disc,['rabbit@rabbit-1']}]}]
...done.
不再有正在运行的节点。
您可以对其他节点(兔子2和Rabbit-3)重复该过程,并查看它们仅了解自己。
Erlang Cookie
在创建集群之前,集群中的所有节点必须具有相同的cookie。 cookie是Erlang运行时用来标识节点的文件。 它位于/var/lib/rabbitmq/.erlang.cookie中。 只需将内容从Rabbit-1复制到Rabbit-2和Rabbit-3。
将节点聚在一起
要将这些单独的节点分组为一个凝聚性集群,需要进行一些工作。 步骤如下:
- 有一个正在运行的节点(例如rabbit-1)。
- 停止另一个节点(例如rabbit-2)。
- 重置停止的节点(兔子2)。
- 将另一个节点群集到根节点。
- 启动停止的节点。
我们开工吧。 ssh进入Rabbit-2并运行以下命令:
sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster rabbit@rabbit-1
现在输入: sudo rabbitmqctl cluster_status
。
输出应为:
Cluster status of node 'rabbit@rabbit-2' ...
[{nodes,[{disc,['rabbit@rabbit-1','rabbit@rabbit-2']}]}]
...Done.
As you can see both nodes are now clustered. If you repeat this on rabbit-1 you'll get following output:
Cluster status of node 'rabbit@rabbit-1' ...
[{nodes,[{disc,['rabbit@rabbit-1','rabbit@rabbit-2']}]},
{running_nodes,['rabbit@rabbit-1']},
{partitions,[]}]
...done.
现在,您可以启动Rabbit-2。
sudo rabbitmqctl start_app
如果再次检查状态,则两个节点都将运行:
Cluster status of node 'rabbit@rabbit-2' ...
[{nodes,[{disc,['rabbit@rabbit-1','rabbit@rabbit-2']}]},
{running_nodes,['rabbit@rabbit-1','rabbit@rabbit-2']},
{partitions,[]}]
...done.
请注意,两个节点都是磁盘节点,这意味着它们将元数据存储在磁盘上。 让我们添加Rabbit-3作为RAM节点。 ssh到Rabbit-3并发出以下命令:
sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster --ram rabbit@rabbit-2
sudo rabbitmqctl start_app
检查状态显示:
Cluster status of node 'rabbit@rabbit-3' ...
[{nodes,[{disc,['rabbit@rabbit-2','rabbit@rabbit-1']},
{ram,['rabbit@rabbit-3']}]},
{running_nodes,['rabbit@rabbit-1','rabbit@rabbit-2','rabbit@rabbit-3']},
{partitions,[]}]
...done.
所有群集节点都在运行。 Disc节点为Rabbit-1和Rabbit-2,RAM节点为Rabbit-3。
恭喜你! 您有一个正常的RabbitMQ集群。
现实世界中的并发症
如果要更改群集配置会怎样? 在群集中添加和删除节点时,必须使用外科手术的精度。
如果尚未重启节点,但是您尝试继续使用stop_app
, reset
和start_app
什么? 好吧,表面上来说stop_app命令将成功执行,并返回“ done”。 即使目标节点已关闭。 但是,随后的reset命令将失败,并显示一条令人讨厌的消息。 我花了很多时间尝试解决这个问题,因为我认为问题是某些配置选项仅影响了重置。
另一个陷阱是,如果要重置最后一个磁盘节点,则必须使用force_reset
。 在一般情况下,尝试找出哪个节点是最后一个磁盘节点并非易事。
RabbitMQ还支持通过配置文件进行集群。 当您的磁盘节点启动时,这非常好,因为重新启动的RAM节点将仅基于配置文件进行集群,而无需您明确地对其进行集群。 同样,当您尝试恢复损坏的群集时,它不会运行。
可靠的RabbitMQ集群
归结为:您不知道哪个磁盘节点发生故障。 您不知道每个节点的集群元数据(也许在重置时它掉线了)。 要启动所有节点,我使用以下算法:
- 启动所有节点(至少最后一个光盘节点应能够启动)。
- 如果甚至没有一个节点可以启动,那么您将无所适从。 救命吧。
- 跟踪所有无法启动的节点。
- 尝试启动所有失败的节点。
- 如果某些节点第二次启动失败,则需要执行操作。 救命吧。
只要您的最后一个磁盘节点在物理上正常,此算法就可以工作。
一旦所有群集节点都启动,就可以重新配置它们(请记住,您不确定每个节点的群集元数据是什么)。 关键是强制重置每个节点。 这样可以确保从所有节点中删除任何先前群集配置的痕迹。 首先对一个磁盘节点执行此操作:
stop_app
force_reset
start_app
然后,对于其他每个节点(磁盘或RAM):
stop_app
force_reset
join_cluster [list of disc nodes]
start_app
远程控制集群
您可以通过SSH进入每个框,并在每个框上手动执行上述步骤。 可以,但是很快就会变旧。 另外,如果要作为自动测试的一部分来构建和拆除群集,这也是不切实际的。
一种解决方案是使用Fabric 。 我遇到的一个严重难题是,当我手动执行构建集群算法时,它可以完美运行,但是当我使用Fabric时,它神秘地失败了。 经过一些调试后,我注意到节点已成功启动,但是当我尝试使用stop_app时,节点已关闭。 事实证明,这是我的Fabric新手错误。 当您使用Fabric发出远程命令时,它将在远程计算机上启动新的Shell。 命令完成后,将关闭外壳程序,并向其所有子进程(包括Erlang节点)发送SIGHUP(挂起信号)。 使用nohup可以解决这一问题。 另一个更强大的选项是将RabbitMQ作为服务(守护程序)运行。
以编程方式管理集群
管理意味着创建虚拟主机,用户,交换和队列,设置权限以及将队列绑定到交换。 如果尚未安装,则应该做的第一件事就是安装管理插件。 我不确定为什么必须自己启用它。 默认情况下应启用它。
Web UI非常棒,您一定要熟悉它。 但是,要远程管理集群,可以使用RESTful管理API。 还有一个名为Rabbitmqadmin的Python命令行工具,需要Python 2.6+。 使用rabbitmqadmin非常简单。 我发现的唯一问题是,我只能使用默认的来宾帐户来管理集群。 我创建了另一个名为“ admin”的管理员用户,将其权限设置为全部(配置/读取/写入),并给其添加了标签“ administrator”(管理API的附加要求),但我一直遇到权限错误。
Elmer项目允许您将集群配置指定为Python数据结构(请参见sample_config.py),并将为您进行所有设置。
带回家点
- RabbitMQ很酷。
- 集群管理员的故事并非一帆风顺。
- 程序管理是关键。
- Fabric是一个很棒的工具,可以远程控制多个Unix机器。
翻译自: https://code.tutsplus.com/tutorials/managing-your-rabbitmq-cluster--cms-25597