RabbitMQ 配置初步
Table of Contents
安装
rabbitmq 的安装分两部分,rabbitmq-server 自身的安装以及其依赖 erlang 的安装。
-
rabbitmq-server:
rabbitmq-server 的安装包 fedora 系统安装源有提供,epel 也有提供。 -
erlang:
erlang包的几个来源是:- EPEL:
Red Hat/fedora 官方包,包被分解为多个小包,版本不太新。 - Erlang Solutions:
包版本最新,提供 yum 安装源安装和单独下载安装的包。 - Erlang from RabbitMQ:
经过裁减的,只包含 rabbitmq 所需功能的包。
- EPEL:
安装完之后,通过 service rabbitmq-server start 来启动服务。默认配置下即可
成功运行 rabbitmq-server。
查看 rabbitmq 状态:
rabbitmqctl status
进一步的配置请继续向下。
配置简介
配置文件
RabbitMQ 的配置有三个来源:环境变量,配置文件和运行时参数。
-
环境变量
RabbitMQ 的环境变量定义在 /etc/rabbitmq/rabbitmq-env.conf 中,位置不可指定。值得一提的是,RabbitMQ对环境变量的解析顺序为:
1.首先是在 shell 中形如 RABBITMQvarname 的变量
2.其次是在配置文件 rabbitmq-env.conf 中 var_name 变量
3.最后是 RabbitMQ 中预定义的默认值 -
配置文件
RHEL/CentOS 下配置文件默认即是 /etc/rabbitmq/rabbitmq.config。
该配置文件的位置可配,指定环境变量 RABBITMQCONFIGFILE
或者在 /etc/rabbitmq/rabbitmq-env.conf 中定义 CONFIG_FILE 都可以。
在 rabbitmq 的日志中有如下一行显示配置文件路径:config file(s) : /etc/rabbitmq/rabbitmq.config
-
运行时参数
还有另外一类特定的配置参数,要么它需要保持在所有 rabbitmq 节点上保持一致,
要么它在运行时会发生变化,这类参数可以使用 rabbitmqctl 来配置。rabbitmqctl set_parameter {-p vhost} component_name name value rabbitmqctl clear_parameter {-p vhost} component_name name rabbitmqctl list_parameters {-p vhost}
用户管理
首次启动 RabbitMQ 时,RabbitMQ 会初始化自己的数据库,并建立如下资源:
-
一个默认虚拟主机,名称为”/”
查看虚拟主机:
rabbitmqctl list_vhosts
-
一个guest用户,密码为 guest,全权访问”/”虚拟主机
查看所有用户:
rabbitmqctl list_users
guest 用户是不安全的,建议删除或者更改其密码。
- 删除:
rabbitmqctl delete_user guest
- 更改密码:
rabbitmqctl change_password guest <password>
为了安全,通常不使用 guest 用户,所以需要创建自定义用户,示例:
rabbitmqctl add_user nova <password>
防火墙
根据配置不同,RabbitMQ 会使用很多 tcp 端口:
4369 (epmd), 25672 (Erlang distribution)
5672, 5671 (启用了 或者 未启用 TLS 的 AMQP 0-9-1)
15672 (如果管理插件被启用)
61613, 61614 (如果 STOMP 被启用)
1883, 8883 (如果 MQTT 被启用)
当配置了 RabbitMQ 集群后,还有额外端口:
在 /etc/rabbitmq/rabbitma.config 中 inet_dist_listen_min 和 inet_dist_listen_max 所
限定的端口。
system limits
rabbitmq 会维持大量的网络连接,所以系统允许打开的最大文件数需要调整。
可以通过 ulimit -n 为单个用户环境设定该值,
或者通过 /etc/security/limits.conf 在系统范围内更改。
RabbitMQ 集群
本节示例创建一个五节点的 rabbitmq 集群,名称分别为:
- rabbit
- rabbit1
- rabbit2
- rabbit3
- rabbit4
在开始下面配置之前,需要将以上主机名写入各节点 /etc/hosts 文件。
只有主机名可正常解析的情况下,以下配置才可继续。
手动创建集群
-
同步 erlang cookie
rabbitmq 使用 erlang 语言写的,erlang 节点之间要通信需要有相同的 cookie。
所谓 cookie 是由数字和字母组成一个字符串,长度任意。
创建 rabbitmq 集群的第一步即是同步 cookie。
Linux 系统的 erlang cookie 通常在 /var/lib/rabbitmq/.erlang.cookie。
只需要确保每个 rabbitmq 节点上的该文件一致即可。
最简单的做法就是在某一个节点上生成 cookie,然后复制到其它节点上。
rabbitmq-server 初次启动时会自动生成 cookie,你也可以自已指定 cookie。如果之前未曾启动,在 rabbit 上启动 rabbitmq 来生成 cookie (手动方式):
rabbit$ rabbitmq-server -detached
从 rabbit 上把 cookie 复制到其它节点:
for i in `seq 1 4` do scp /var/lib/rabbitmq/.erlang.cookie rabbit$i:/var/lib/rabbitmq/.erlang.cookie done
-
启动独立节点
rabbitmq 集群的构建是通过将已有节点重新配置的方式来加入集群的。
所以需要在每个节点上把 rabbitmq-server 启动一次:rabbit1$ rabbitmq-server -detached rabbit2$ rabbitmq-server -detached rabbit3$ rabbitmq-server -detached rabbit4$ rabbitmq-server -detached
-
配置集群
在除 rabbit 之外的节点上,调整 rabbitmq。rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rabbit rabbitmqctl start_app
查看一下集群的状态,
rabbit$ rabbitmqctl cluster_status Cluster status of node 'rabbit@rabbit' ... [{nodes,[{disc,['rabbit@rabbit1','rabbit@rabbit2', 'rabbit@rabbit3','rabbit@rabbit4', 'rabbit@rabbit']}]}, {running_nodes,['rabbit@rabbit1','rabbit3@rabbit2', 'rabbit@rabbit3','rabbit1@rabbit4', 'rabbit@rabbit']}, {cluster_name,<<"rabbit@rabbit">>}, {partitions,[]}] ...done.
以上 nodes 一行是本集群所有的节点名称,running_nodes 则是运行状态的节点名称。
重启集群
在每个节点上执行如下命令停止 rabbitmq
rabbitmqctl stop
再要重新启动,调用
rabbitmq-server -detached
注意: 对于所有节点都关闭了的集群,重新启动的时候:
- 最后关闭的节点必须最先启动。
- 如果最后关闭的节点没有先启动,其它节点启动时会等待 30 秒,然后失败放弃。
-
如果最后关闭的节点由于某种原因启动不了,其它节点启动时可以使用如下命令删除掉。
rabbitmqctl forget_cluster_node rabbit@rabbit
-
如果集群故障,所有节点同时停掉,例如同时断电的情况,所有节点都认为其它节点是
最后停掉的。 这种情况下可以使用 force_boot 命令来强制启动节点。注意:force_boot命令在 rabbitmq 3.4 版本以上才有。目前 epel7 源中的版本 3.3.5 还没有。
在没有 force_boot 命令的情况下,尝试同时启动各个节点也可以重新启动集群。
破坏集群
对于每个集群节点,使用如下命令可以使其脱离集群,从而破坏整个集群:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
特殊的,当某一个节点 (如 rabbit4) 已经连接不上,此时可以在在线的节点上执行如下命令:
rabbitmqctl forget_cluster_node rabbit4@rabbit
之后,如果 rabbit4 系统又恢复了,想要重新加入启动 rabbitmq,会出错:
rabbitmqctl start_app ( or rabbitmq-server -detached )
{error,{inconsistent_cluster,"Node 'rabbit4@rabbit4' thinks it's clustered with node 'rabbit@rabbit', but 'rabbit@rabbit' disagrees"}}
此时需要先重置 rabbit4 后再重启:
rabbitmqctl reset ( or rm -rf /var/lib/rabbitmq/mnesia/rabbit
rabbitmqctl start_app ( or rabbitmqctl -detached )
自动创建集群
除了使用上面手动的方式构建集群之外,也可以通过指定配置文件来构建集群,只需要在
/etc/rabbitmq/rabbitmq.config 中写入节点的列表即可:
[
...
{rabbit, [
...
{cluster_nodes, {['rabbit@rabbit1', 'rabbit@rabbit2', 'rabbit@rabbit3'], disc}},
...
]},
...
].
该种方式存在的问题是:只对于从未启动过的或重置过的 rabbitmq 节点可用,其它的不行。
fuel 中的 rabbitmq
-
fuel 中的 rabbitmq 由 pacemaker 管理
其控制脚本路径为 /usr/lib/ocf/resource.d/mirantis/rabbitmq-server
多节点环境下,rabbitmq 节点有 Master 和 Slave 两种身份。确认 rabbitmq-server 状态:
crm resource list
在其中找到关于 rabbitmq-server 的信息,类似:
Master/Slave Set: master_p_rabbitmq-server [p_rabbitmq-server] Masters: [ node-3.domain.tld ] Slaves: [ node-1.domain.tld node-2.domain.tld ]
如果有某个节点上服务已停止,则有节点状态为 Stopped:
Master/Slave Set: master_p_rabbitmq-server [p_rabbitmq-server] Masters: [ node-1.domain.tld ] Slaves: [ node-3.domain.tld ] Stopped: [ node-2.domain.tld ]
或者某个节点上服务出现故障,则有节点状态为 FAILED:
Master/Slave Set: master_p_rabbitmq-server [p_rabbitmq-server] p_rabbitmq-server (ocf::mirantis:rabbitmq-server): FAILED Masters: [ node-11.eayun.test ] Slaves: [ node-10.eayun.test ]
你也可以使用如下命令来查看状态:
crm resource show master_p_rabbitmq-server
-
使用 rabbitmqctl 查看集群状态
使用 pacemnaker 提供的工具查看 rabbitmq 的状态,所查看到的状态仅仅是 rabbitmq-server
服务的状态,更准确的状态需要通过 rabbitmq 自身提供的工具。查看单一节点的状态 (进程 pid,版本,在运行的程序,占用内存,侦听的端口等详细信息):
rabbitmqctl status
查看集群状态 (集群中某节点的运行状态):
rabbit$ rabbitmqctl cluster_status Cluster status of node 'rabbit@rabbit' ... [{nodes,[{disc,['rabbit@rabbit1','rabbit@rabbit2', 'rabbit@rabbit3','rabbit@rabbit4', 'rabbit@rabbit']}]}, {running_nodes,['rabbit@rabbit1','rabbit3@rabbit2', 'rabbit@rabbit3','rabbit1@rabbit4', 'rabbit@rabbit']}, {cluster_name,<<"rabbit@rabbit">>}, {partitions,[]}] ...done.
返回结果中,nodes 一行是本集群所有的节点名称,runningnodes 则是运行状态的节点名称。
不在 runningnodes 中而在 nodes 中的节点即为故障的节点。
抛开所有节点不谈,只要 partitions 不为空,则集群状态已出现故障。 -
配置部分
-
端口
fuel 所部署的 OpenStack中 haproxy 作为 rabbitmq 的负载均衡器,它监听 5672
端口,然后将请求转发至 5673。然而就目前观察,OpenStack 中并没有服务使用了 haproxy
提供的该 5672 端口的服务,各 OpenStack 服务都是直接连接节点的 5673 端口。
0 0 ACCEPT tcp — * * 172.16.100.2 0.0.0.0/0 multiport sports 4369,5672,15672,41055,55672,61613 /* 003 remote rabbitmq /
98358 5901K ACCEPT tcp — * * 0.0.0.0/0 0.0.0.0/0 multiport ports 4369,5672,5673,41055 / 106 rabbitmq */-
system limits
Fuel 在 /etc/security/limits.conf 中设置了 system limits:
最大文件数的 soft limits 102400,hard limits 为 112640。 -
vhosts 和 user
只有一个默认虚拟主机,列出虚拟机主机:
# rabbitmqctl list_vhosts Listing vhosts ... / ...done
只有一个用户 nova,所有 OpenStack 服务都使用该用户连到 rabbitmq,列出用户:
# rabbitmqctl list_users Listing users ... nova [administrator] ...done.
-