端口说明:
5672:消费者访问的端口15672:web管理端口25672:集群状态通信端口1. 安装
安装 RabbitMQ 之前要安装 Erlang,需要先到 RabbitMQ官网 看下版本对应关系。
Erlang下载和安装-PackageCloud
RabbitMQ 下载和安装-官方文档1.1 单机部署
1.1.1 CentOS 7
```bash一键部署 Erlang 仓库
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | bash
安装 Erlang
yum -y install erlang
一键部署 RabbitMQ 仓库
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | bash
安装 RabbitMQ
yum -y install rabbitmq-server
启动服务
systemctl enable —now rabbitmq-server.service
<a name="maylz"></a>### 1.1.2 CentOS 8<a name="FSRRe"></a>#### 官方源安装```bash# 添加 repo 仓库vim /etc/yum.repos.d/rabbitmq.repo[rabbitmq_erlang]name=rabbitmq_erlangbaseurl=https://packagecloud.io/rabbitmq/erlang/el/8/$basearchrepo_gpgcheck=1gpgcheck=1enabled=1gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkeysslverify=1sslcacert=/etc/pki/tls/certs/ca-bundle.crtmetadata_expire=300[rabbitmq_erlang-source]name=rabbitmq_erlang-sourcebaseurl=https://packagecloud.io/rabbitmq/erlang/el/8/SRPMSrepo_gpgcheck=1gpgcheck=0enabled=1gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkeysslverify=1sslcacert=/etc/pki/tls/certs/ca-bundle.crtmetadata_expire=300[rabbitmq_rabbitmq-server]name=rabbitmq_rabbitmq-serverbaseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/8/$basearchrepo_gpgcheck=1gpgcheck=0enabled=1gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkeysslverify=1sslcacert=/etc/pki/tls/certs/ca-bundle.crtmetadata_expire=300[rabbitmq_rabbitmq-server-source]name=rabbitmq_rabbitmq-server-sourcebaseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/8/SRPMSrepo_gpgcheck=1gpgcheck=0enabled=1gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkeysslverify=1sslcacert=/etc/pki/tls/certs/ca-bundle.crtmetadata_expire=300# 导入 GPG KEYrpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.ascrpm --import https://packagecloud.io/rabbitmq/erlang/gpgkeyrpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey# 安装 Erlangdnf -y install erlang# 安装 RabbitMQdnf -y install rabbitmq-server# 启动服务systemctl enable --now rabbitmq-server.service
1.1.3 Ubuntu20.04
[root@rabbitmq-01:~]# apt update# 安装 apt HTTPS 传输[root@rabbitmq-01:~]# apt install apt-transport-https# 添加仓库签名密钥[root@rabbitmq-01:~]# curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor > /usr/share/keyrings/com.rabbitmq.team.gpg[root@rabbitmq-01:~]# curl -1sLf "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xf77f1eda57ebb1cc" | sudo gpg --dearmor > /usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg[root@rabbitmq-01:~]# curl -1sLf "https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey" | sudo gpg --dearmor > /usr/share/keyrings/io.packagecloud.rabbitmq.gpg# 添加 PackageCloud 仓库源[root@rabbitmq-01:~]# tee /etc/apt/sources.list.d/rabbitmq.list <<EOFdeb [signed-by=/usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg] http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic maindeb-src [signed-by=/usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg] http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic maindeb [signed-by=/usr/share/keyrings/io.packagecloud.rabbitmq.gpg] https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ focal maindeb-src [signed-by=/usr/share/keyrings/io.packagecloud.rabbitmq.gpg] https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ focal mainEOF# 安装 Erlang[root@rabbitmq-01:~]# apt update[root@rabbitmq-01:~]# apt install -y erlang-base \erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \erlang-runtime-tools erlang-snmp erlang-ssl \erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl# 安装 RabbitMQ[root@rabbitmq-01:~]# apt install rabbitmq-server -y --fix-missing# 自启动服务[root@c7-04 ~]# systemctl enable rabbitmq-server.service
1.2 RabbitMQ 集群
1.2.1 集群队列模式
Rabbitmq 集群有两种方式:
- 普通模式:创建好 RabbitMQ 集群之后的默认模式。queue 创建之后,如果没有其它 policy,消息实体只存在于其中 一个节点。例如有 A、B 两个 Rabbitmq 节点,他们仅有相同的元数据,即队列结构,但队列的数据仅保存有一份,即创建该队列的 rabbitmq 节点(A 节点),当消息进入 A 节点的 Queue 中后,consumer 从 B 节点拉取时,RabbitMQ 会临时在 A、B 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer,所以 consumer 可以连接每一个节点来取消息,但该模式存在一个问题就是当 A 节点故障后,B 节点无法取到 A 节点中还未消费的消息实体。
- 镜像模式:把需要的服务器做成镜像队列。数据存在于多个节点,属于 RabbitMQ 的 HA 方案(镜像模式是在普通模式的基础上,增加一些镜像策略)该模式解决了普通模式中的数据丢失问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在 consumer 取数据时临时拉取,该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置 policy,然后客户端创建队列的时候,rabbitmq 集群根据“队列名称”自动设置是普通集群模式或镜像队列。
1.2.2 集群节点类型
- 内存节点:只将数据保存到内存中。
- 磁盘节点:保存数据到内存和磁盘。
内存节点虽然不写入磁盘,但是它执行比磁盘节点要好,集群中,只需要一个磁盘节点来保存数据就足够了如果集群中只有内存节点,那么不能全部停止它们,否则所有数据消息在服务器全部停机之后都会丢失。
推荐设计架构:在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式,其它节点使用内存模式,内存节点无访问速度更快,由于磁盘 IO 相对较慢,因此可作为数据备份使用。
1.2.3 集群实现
RabbitMQ 基于Erlang编写,Erlang 语言天生具备分布式特性(通过同步 Erlang 集群各节点的 magic cookie 来实现)。因此,RabbitMQ 天然支持 Clustering。使得 RabbitMQ 不需要像 ActiveMQ、Kafka 那样通过 ZooKeeper 分别来实现 HA 方案和保存集群的元数据。这个 magic cookie 存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须保证各节点 cookie 保持一致,否则节点之间就无法通信。
[root@rabbitmq-01:~]# ll /var/lib/rabbitmq/.erlang.cookie-r-------- 1 rabbitmq rabbitmq 20 Oct 18 00:00 /var/lib/rabbitmq/.erlang.cookie[root@rabbitmq-01:~]# cat /var/lib/rabbitmq/.erlang.cookieYQYFOFYLVHRYBNXSKVDS
1.3 集群部署详解
1.3.1 部署环境
三台集群 ip 和 主机名如下:
# 设置主机名hostnamectl set-hostname rabbitmq-01 && bashhostnamectl set-hostname rabbitmq-02 && bashhostnamectl set-hostname rabbitmq-03 && bashcat >>/etc/hosts <<EOF10.0.0.91 rabbitmq-01 rabbitmq-01.wuvikr.top10.0.0.92 rabbitmq-02 rabbitmq-02.wuvikr.top10.0.0.93 rabbitmq-03 rabbitmq-03.wuvikr.topEOF
1.3.2 安装 RabbitMQ
安装过程祥见 1.1 单机部署 章节,这里不再重复。部署完成以后不要启动服务。
1.3.3 复制 .erlang.cookie 文件
保证三台机器上的 /var/lib/rabbitmq/.erlang.cookie 文件一致,否则节点之间就无法通信。这里拷贝 10.0.0.91 上的文件到其他另外两个节点。
[root@rabbitmq-01:~]# scp -p /var/lib/rabbitmq/.erlang.cookie 10.0.0.92:/var/lib/rabbitmq/.erlang.cookie[root@rabbitmq-01:~]# scp -p /var/lib/rabbitmq/.erlang.cookie 10.0.0.93:/var/lib/rabbitmq/.erlang.cookie
1.3.4 启动 RabbitMQ 服务
[root@rabbitmq-01:~]# systemctl start rabbitmq-server[root@rabbitmq-02:~]# systemctl start rabbitmq-server[root@rabbitmq-03:~]# systemctl start rabbitmq-server
1.3.5 创建集群
将 rabbitmq-01 作为集群,将 rabbitmq-02 和 rabbitmq-03 两台机器作为内存节点加入 rabbitmq-01 集群。
# 停止服务[root@rabbitmq-02:~]# rabbitmqctl stop_app[root@rabbitmq-03:~]# rabbitmqctl stop_app# 清空元数据[root@rabbitmq-02:~]# rabbitmqctl reset[root@rabbitmq-03:~]# rabbitmqctl reset# 添加到集群当中,并成为内存节点,不加--ram 默认是磁盘节点[root@rabbitmq-02:~]# rabbitmqctl join_cluster rabbit@rabbitmq-01 --ram[root@rabbitmq-03:~]# rabbitmqctl join_cluster rabbit@rabbitmq-01 --ram# 启动服务[root@rabbitmq-02:~]# rabbitmqctl start_app[root@rabbitmq-03:~]# rabbitmqctl start_app
1.3.6 查看集群状态
[root@rabbitmq-01:~]# rabbitmqctl cluster_statusCluster status of node rabbit@rabbitmq-01 ...BasicsCluster name: rabbit@rabbitmq-01Disk Nodesrabbit@rabbitmq-01RAM Nodesrabbit@rabbitmq-02rabbit@rabbitmq-03Running Nodesrabbit@rabbitmq-01rabbit@rabbitmq-02rabbit@rabbitmq-03Versionsrabbit@rabbitmq-01: RabbitMQ 3.9.7 on Erlang 24.1.2rabbit@rabbitmq-02: RabbitMQ 3.9.7 on Erlang 24.1.2rabbit@rabbitmq-03: RabbitMQ 3.9.7 on Erlang 24.1.2Maintenance statusNode: rabbit@rabbitmq-01, status: not under maintenanceNode: rabbit@rabbitmq-02, status: not under maintenanceNode: rabbit@rabbitmq-03, status: not under maintenanceAlarms(none)Network Partitions(none)ListenersNode: rabbit@rabbitmq-01, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq-01, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Node: rabbit@rabbitmq-02, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq-02, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Node: rabbit@rabbitmq-03, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq-03, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Feature flagsFlag: implicit_default_bindings, state: enabledFlag: maintenance_mode_status, state: enabledFlag: quorum_queue, state: enabledFlag: stream_queue, state: enabledFlag: user_limits, state: enabledFlag: virtual_host_metadata, state: enabled
1.3.8 开启镜像模式
在任意一台节点上执行下面的命令即可:
rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
注意:这里指定了 ha-mode 的值为 all ,代表消息会被同步到所有节点的相同队列中。当集群机器较多时,复制的性能开销会非常大,此时再使用 all 就不太合适了,需要选择合适的复制系数。通常可以遵循过半写原则,即对于一个节点数为 n 的集群,只需要同步到 n/2+1 个节点上即可。此时需要同时修改镜像策略为 exactly,并指定复制系数 ha-params,具体命令如下:
rabbitmqctl set_policy ha-two "^" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
2. 其他配置
2.1 开启 Web 管理界面
rabbitmq-plugins enable rabbitmq_management
2.2 配置文件
vim /etc/rabbitmq/rabbitmq.conf...# 配置远程登录loopback_users.guest = false
3. 使用和操作
3.1 操作用户并授权
# 创建用户rabbitmqctl add_user rabbitmq '12345678'# 设置用户[管理员]标签rabbitmqctl set_user_tags rabbitmq administrator# 创建virtual hostrabbitmqctl add_vhost /vhost1# 为用户授权可以访问的[virtual host]和操作类型[配置、读、写]rabbitmqctl set_permissions -p /vhost1 rabbitmq '.*' '.*' '.*'# 删除一个用户rabbitmqctl delete_user Username# 修改用户的密码rabbitmqctl change_password Username Newpassword# 查看当前用户列表rabbitmqctl list_users
3.2 RabbitMQ 角色权限
none:不能访问 management_plugin(图形管理界面)management:单一 virtual hosts 用户,用户仅可以通过 AMQP 协议查看和自己相关的信息。policymaker:单一 virtual hosts 用户,另外可以查看、创建和删除自己的 virtual hosts 所属的 policies 和 parameters。monitoring:监控用户,可以查看所有信息。administrator:管理员用户。3.3 rabbitmqctl 命令详解
命令格式:rabbitmqctl [-n <node>] [-q] <command> [<command options>]3.3.1 基本命令
```bash停止运行rabbitmq
rabbitmqctl stop
停止运行rabbitmq上的应用
rabbitmqctl stop_app
等待rabbitmq服务启动
rabbitmqctl wait
初始化node状态(需要先执行rabbitmqctl stop_app)
rabbitmqctl reset
强制初始化node状态
rabbitmqctl force_reset
轮转日志文件
rabbitmqctl rotate_logs
<a name="aP1VC"></a>### 3.3.2 cluster集群管理```bash# 默认node以disc node加入集群,--ram表示node以ram node加入集群中(要先执行rabbitmqctl stop_app)rabbitmqctl join_cluster <node name> --ram# 显示cluster中的所有noderabbitmqctl cluster_status# 改变一个cluster中node的模式,注意,转换前必须先停止节点,不能把一个集群中唯一的disk node转化为ram noderabbitmqctl change_cluster_node_type disc | ram# 远程移除cluster中的一个node,前提是该node必须处于offline状态,如果是online状态,则需要加--offline参数。rabbitmqctl forget_cluster_node --offline# 远程更新cluster中的noderabbitmqctl update_cluster_nodes clusternode# 同步镜像队列rabbitmqctl sync_queue queue# 取消同步镜像队列rabbitmqctl cancel_sync_queue queue
3.3.3 用户管理
# 添加rabbitmq用户rabbitmqctl add_user <username> <password># 删除rabbitmq用户rabbitmqctl delete_user <username># 改变rabbitmq用户密码rabbitmqctl change_password <username> <newpassword># 清除用户密码,禁止用户登录rabbitmqctl clear_password <username># 设置用户标签rabbitmqctl set_user_tags <username> <tag1> <tag2> ... <tag_n># 列出用户rabbitmqctl list_users# 创建一个vhostsrabbitmqctl add_vhost <vhostpath># 删除一个vhostsrabbitmqctl delete_vhost <vhostpath># 列出vhostsrabbitmqctl list_vhosts <vhostinfoitem1> <vhostinfoitem2> ... <vhostinfoitem_n># 针对一个vhosts 给用户赋予相关权限rabbitmqctl set_permissions [-p <vhostpath>] <user> <conf> <write> <read># 清除一个用户对vhosts的权限rabbitmqctl clear_permissions [-p <vhostpath>] <username># 列出哪些用户可以访问该vhostsrabbitmqctl list_permissions [-p <vhostpath>]#列出该用户的访问权限rabbitmqctl list_user_permissions <username># 修改vhost路径参数rabbitmqctl set_parameter [-p <vhostpath>] <component_name> <key> <value># 清除vhost路径参数rabbitmqctl clear_parameter [-p <vhostpath>] <component_name> <key># 列出vhost路径参数rabbitmqctl list_parameters [-p <vhostpath>]
3.3.4 策略管理
# priority:整数优先级 apply-to:策略应用类型范围,有[all、queues、exchange] name:策略名称 pattern:匹配资源正则表达式 definition:json格式设置的策略rabbitmqctl set_policy [-p <vhostpath>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern> <definition(json)>#清除一个策略rabbitmqctl clear_policy [-p <vhostpath>] <name># 列出已有的策略rabbitmqctl list_policies [-p <vhostpath>]# queues exchanges# 返回queue的信息,如果省略了-p参数,则默认显示的是"/"vhosts的信息。rabbitmqctl list_queues [-p <vhostpath>] [<queueinfoitem> ...]# 返回exchange的信息rabbitmqctl list_exchanges [-p <vhostpath>] [<exchangeinfoitem> ...]# 返回绑定信息rabbitmqctl list_bindings [-p <vhostpath>] [<bindinginfoitem> ...]# 返回链接信息rabbitmqctl list_connections [<connectioninfoitem> ...]# 返回目前所有的channelsrabbitmqctl list_channels [<channelinfoitem> ...]# 返回consumersrabbitmqctl list_consumers [-p <vhostpath>]# 显示broker的状态rabbitmqctl status# 显示环境参数的信息rabbitmqctl environment# 返回一个服务状态reportrabbitmqctl report# 返回一个服务状态evalrabbitmqctl eval <expr>
3.4 手动安装插件
RabbitMQ 提供很多插件,需要手动去官方插件社区下载安装。下载好对应版本的插件后放在/usr/lib/rabbitmq/lib/rabbitmq_server-<Version>/plugins目录下,然后使用rabbitmq-plugins enable <Plugin-Name>命令启动即可。
4. 报错解决
4.1 统计数据库内存爆满
4.1.1 现象
日志:
************************************************************* Publishers will be blocked until this alarm clears *************************************************************=INFO REPORT==== 16-Jan-2022::09:31:35 ===vm_memory_high_watermark clear. Memory used:8069568592 allowed:13426866585=WARNING REPORT==== 16-Jan-2022::09:31:35 ===memory resource limit alarm cleared on node rabbit@Agent03=WARNING REPORT==== 16-Jan-2022::09:31:35 ===memory resource limit alarm cleared across the cluster=INFO REPORT==== 16-Jan-2022::09:37:28 ===vm_memory_high_watermark set. Memory used:14187251472 allowed:13426866585=WARNING REPORT==== 16-Jan-2022::09:37:28 ===memory resource limit alarm set on node rabbit@Agent03.
管理界面:<br />
4.1.2 解决方法
统计数据库完全存储在内存中。所有内容都是短暂的。在版本3.6.7之前,stats数据库存储在单个节点上。从版本3.6.7开始,每个节点都有自己的统计数据库,其中包含记录在该节点上的一小部分统计数据。当统计数据库内存过高时可以重新启动统计数据库。
3.6.2版本之前重新启动数据库命令:
rabbitmqctl eval 'exit(erlang:whereis(rabbit_mgmt_db), please_terminate).'
3.6.2-3.6.5版本:
rabbitmqctl eval 'supervisor2:terminate_child(rabbit_mgmt_sup_sup, rabbit_mgmt_sup), rabbit_mgmt_sup_sup:start_child().'
注意:这些命令必须在托管数据库的节点上执行。
从 3.6.7 版本开始,可以使用每个节点重置数据库,另外3.6.10版本的 management 控制台已经可见 reset 按钮
rabbitmqctl eval 'rabbit_mgmt_storage:reset().'
重置所有节点上的整个管理数据库:
rabbitmqctl eval 'rabbit_mgmt_storage:reset_all().'
