RabbitMQ介绍
RabbitMQ 是使用Erlang语言开发的基于AMQP标准的开源实现,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不错
RabbitMQ的特点
1、保证可靠性(Reliability):使用持久化、传输确认、发布确认等机制
2、灵活的路由功能(Flexible Routing):在消息进入队列之前,通过Exchange(交换器)来路由消息,对应典型的路由功能,RabbitMQ提供了内置的一些Exchange来实现、针对复杂的路由功能,可以将多个Exchange绑定在一起,也可以通过插件来实现自己的Exchange
3、支持消息集群(Clustering):多台RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker
4、具有高可用性(Highly Available):队列可以在集群中的机器进行镜像,在部分节点出现问题的情况下队列仍然可用
5、支持多种协议(Multi-protocol):RabbitMQ除了支持AMQP协议之外,还通过插件方式支持其它消息队列协议,比如STOMP、MQTT等
6、支持多语言客户端(Many Client):几乎支持所有常用的语言
7、提供管理界面(Management UI):RabbitMQ提供了一个简单的用户页面,用户可以监控和管理消息
8、提供跟踪机制(Tracing):RabbitMQ提供了消息跟踪机制,如果消息异常,使用者可以查出发生了什么情况
9、提供插件机制(Plugin System):RabbitMQ提供了许多插件,从多方面进行扩展,也可以自己编写自己的插件
RabbitMQ架构
架构介绍
- Message(消息):由消息头和消息体组成、消息体是不透明的、消息头由一系列可选属性组成:例如routing-key路由键、priority消息优先级、delivery-mode是否持久化存储等
- Publisher(消息生产者):向交换机发布消息的客户端应用程序
- Exchange(交换器):用来接收消息生产者发布的消息,并将这些消息路由给服务器中的队列
- Binding(绑定):用于消息队列和交换机之间的关联
- Queue(消息队列):用来保存消息直到发送给消费者,是消息的容器,一条消息可以被投入到多个队列中
- Connection(网络连接):例如一个TCP连接
- Channel(信道):多路复用连接中的一条独立的双向数据流通道
- Consumer(消息消费者):从消息队列中取得消息的客户端应用程序
- Virtual Host(虚拟主机):每个vhost都是一台缩小版的RabbitMQ、它拥有自己的队列、交换器、绑定和权限机制,默认的vhost是"/"
- Broker(消息队列服务器实体)
RabbitMQ账户角色
- administrator:可以登录控制台、查看所有信息、并对rabbitmq进行管理
- monToring:监控者;登录控制台,查看所有信息
- policymaker:策略制定者;登录控制台指定策略
- managment:普通管理员;登录控制
Rabbit模式
大概分为以下三种:单一模式、普通模式、镜像模式
单一模式:最简单的情况,非集群模式,即单实例服务。
普通模式:默认的集群模式。
queue创建之后,如果没有其它policy,则queue就会按照普通模式集群。对于Queue来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构,但队列的元数据仅保存有一份,即创建该队列的rabbitmq节点(A节点),当A节点宕机,你可以去其B节点查看,./rabbitmqctl list_queues 发现该队列已经丢失,但声明的exchange还存在。
当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer。
所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连A或B,出口总在A,会产生瓶颈。
该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。
如果做了消息持久化,那么得等A节点恢复,然后才可被消费;如果没有持久化的话,队列数据就丢失了。
镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案。
该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。
该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。
RabbitMQ与Erlang依赖关系
每个RabbitMQ版本都依赖相对应的Erlang版本范围,切记不能跨版本安装,否则RabbitMQ无法正常运行。
RabbitMQ与Erlang依赖关系请参考官网介绍 which-erlang,如下示例
RabbitMQ对操作系统要求
针对windows,暂时没有特别要求,每个版本都有对应的windows安装包。
针对CentOS Linux,从3.10.0之后开始,由于RabbitMQ包管理模块依赖一些特定的系统组件(如OpenSSL 1.1),需要CentOS 8以上提供,所以针对CentOS 7及以下版本不再提供RPM安装包(包括RabbitMQ与Erlang),但RabbitMQ官方提供了通用Linux二进制文件包,可以正常运行RabbitMQ功能。
即,CentOS7通过RPM方式可以安装的最大版本为 3.10.0
RabbitMQ发布方式
RabbitMQ官网各版本ReleaseNote中介绍了,其二进制包与RPM包,可以从 GitHub, Cloudsmith, Package Cloud 获取,其中二进制包只能从GitHub获取,官网安装教程中也提供了相应的链接入口。
RabbitMQ安装
本文按照单实例模式,RPM方式安装。
组件安装操作步骤参考 组件安装部署手册模板,根据不同组件的安装目标,部分操作可以省略。
本文将按照该参考步骤执行。
一、获取组件可执行程序库,包括主程序,此为组件的基本文件
1.RabbitMQ 3.10.0 RPM包已经无法在官网下载,本次通过PackageCloud下载,保存 /usr/local/rabbitmq 目录
在 GitHub ReleaseNote上,3.10.0已经不提供CentOS7 RPM包,GitHub上CentOS7 提供RPM包的最大版本为 3.9.16
2.安装依赖组件
2.1 下载Erlang,保存 /usr/local/erlang 目录
根据RabbitMQ与Erlang版本依赖,我们选择Erlang 23.3.4.11(适应CentOS7的最大版本),RPM包无法在官网下载,本次通过PackageCloud下载
2.2 安装Erlang
[root@localhost erlang]# ls erlang-23.3.4.11-1.el7.x86_64.rpm [root@localhost erlang]# rpm -ivh erlang-23.3.4.11-1.el7.x86_64.rpm [root@localhost rabbitmq]# yum list installed | grep erlang erlang.x86_64 23.3.4.11-1.el7 installed
RPM安装后,Erlang环境变量自动生效
[root@localhost erlang]# erl Erlang/OTP 23 [erts-11.2.2.10] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] Eshell V11.2.2.10 (abort with ^G)
特别关注
其他很多教程提示需要安装 socat 组件,但本次安装过程中,并没有相关提示,原因暂时没有排查,请根据实际情况安装
3.RabbitMQ RPM安装
[root@localhost rabbitmq]# ls rabbitmq-server-3.10.0-1.el7.noarch.rpm [root@localhost rabbitmq]# rpm -ivh rabbitmq-server-3.10.0-1.el7.noarch.rpm [root@localhost rabbitmq]# yum list installed | grep rabbitmq rabbitmq-server.noarch 3.10.0-1.el7 installed
二、安装系统服务
RabbitMQ RPM安装后,自动生成系统服务 rabbitmq-server,可以使用 systemctl 或 service 命令操作。
三、主程序加入到环境变量
RabbitMQ RPM安装后,环境变量自动生效
四、配置文件
RabbitMQ运行需要监听3个端口:
- HTTP服务端口,用于客户端程序连接(默认5672)
- web管理系统端口,用于浏览器登录(默认15672)
- 集群端口,用于集群内部通信(默认25672)
RabbitMQ二进制安装方式,配置文件路径为 【安装目录/etc/rabbitmq】,关于配置文件名称与配置格式,以下将以相同的配置要求对比不同配置方式差异。
配置方式一:
RabbitMQ 3.7版本之前,统一使用 rabbitmq.conf,配置格式为 Erlang 格式,结构如下
- 最后结尾一定要加上点号【.】表示结束,否则启动会报错
- %%为注释
[
{
rabbit,
[
{
tcp_listeners,
[
{"0.0.0.0" ,5673}
]
},
{
loopback_users,
[
]
}
]
},
{
rabbitmq_management,
[
{
listener,
[
{port , 15673},
{ip , "0.0.0.0"}
]
}
]
}
].
配置方式二:
RabbitMQ 3.7版本开始,开始支持新的 sysctl 格式,配合更简单明了,且可读性更高
- 每个配置项一行
- 每个配置项为键值对结构
- #为注释
listeners.tcp.1 = 0.0.0.0:5673
management.tcp.ip = 0.0.0.0
management.tcp.port = 15673
loopback_users.guest = none
特别关注:
虽然sysctl格式优势很明显,但RabbitMQ有一些特殊的配置项(正常使用RabbitMQ不会用到),无法在sysctl下支持,所以RabbitMQ官方在 3.7 版本开始,设计了3个配置文件,如下
- rabbitmq.conf,主配置文件,采用sysctl格式
- advanced.config,补充配置文件,使用 Erlang 格式,为了兼容不被 sysctl 支持的配置项,启动时与主配置文件内容合并
- rabbitmq-env.conf,环境变量文件,很少用到,用于修改RabbitMQ环境相关配置,如修改默认配置文件地址,等
需要特别说明,在RabbitMQ启动后,内部维护配置项依然使用Erlang格式,毕竟底层环境为Erlang。
本文使用sysctl格式配置rabbitmq.conf,路径为 /usr/local/rabbitmq/rabbitmq_server-3.11.3/etc/rabbitmq/rabbitmq.conf,完整内容如下
#监听网络
#方式1.监听所有网络(包括ipv4与ipv6),只配置默认端口
#listeners.tcp.default = 5673
#方式2.监听特定网络,包括IP与端口,如下只监听ipv4
#此配置格式为 listeners.tcp.name = ip:port,其中name没有特殊限制,只要相互区分即可
listeners.tcp.1 = 0.0.0.0:5673
#web管理系统监听网络
management.tcp.ip = 0.0.0.0
management.tcp.port = 15673
#配置回环地址登录的账户,即只能本地登录,默认只有guest账户
#方式1.单用户配置模式:loopback_users.username = bool
#单用户配置模式下,账户除非明确配置,否则默认为false,即可以远程登录,例如配置了 loopback_users.admin = true,没有为guest配置,则guest此时可以远程登录
#方式2.系统统一配置模式:loopback_users = none
#此模式只能指定none,即开放所有账户远程登录,不能配置为多个账户(逗号分隔)
loopback_users.guest = false
特别关注:Erlang配置文件与sysctl配置模板,请参考附录。
五、运行用户
默认使用root运行即可。
六、开机启动
请参考教程 Linux开机启动方案
七、服务启动运行
1.启用web管理系统
web管理系统是RabbitMQ的一个插件,需要先启用才能运行
[root@localhost rabbitmq]# rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@localhost:
rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@localhost...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
set 3 plugins.
Offline change; changes will take effect at broker restart.
2.启动服务
方式1:前台启动,rabbitmq-server,打印启动参数,包括日志路径、配置文件路径
[root@localhost rabbitmq_server-3.11.3]# rabbitmq-server start
2022-11-13 19:36:03.916807+08:00 [notice] <0.44.0> Application syslog exited with reason: stopped
2022-11-13 19:36:03.921853+08:00 [notice] <0.228.0> Logging: switching to configured handler(s); following messages may not be visible in this log output
## ## RabbitMQ 3.11.3
## ##
########## Copyright (c) 2007-2022 VMware, Inc. or its affiliates.
###### ##
########## Licensed under the MPL 2.0. Website: https://rabbitmq.com
Erlang: 25.1 [emu]
TLS Library: OpenSSL - OpenSSL 1.0.2k-fips 26 Jan 2017
Release series support status: supported
Doc guides: https://rabbitmq.com/documentation.html
Support: https://rabbitmq.com/contact.html
Tutorials: https://rabbitmq.com/getstarted.html
Monitoring: https://rabbitmq.com/monitoring.html
Logs: /usr/local/rabbitmq/rabbitmq_server-3.11.3/var/log/rabbitmq/rabbit@localhost.log
/usr/local/rabbitmq/rabbitmq_server-3.11.3/var/log/rabbitmq/rabbit@localhost_upgrade.log
<stdout>
Config file(s): /usr/local/rabbitmq/rabbitmq_server-3.11.3/etc/rabbitmq/rabbitmq.conf
Starting broker... completed with 3 plugins.
方式2:后台启动,rabbitmq-server -detached,或者 nohup rabbitmq-server &,不打印信息,但可以通过服务状态查看
[root@localhost rabbitmq_server-3.11.3]# rabbitmq-server -detached
[root@localhost rabbitmq_server-3.11.3]# rabbitmqctl status
Status of node rabbit@localhost ...
Runtime
OS PID: 15183
OS: Linux
Uptime (seconds): 14
Is under maintenance?: false
RabbitMQ version: 3.11.3
RabbitMQ release series support status: supported
Node name: rabbit@localhost
Erlang configuration: Erlang/OTP 25 [erts-13.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
Crypto library: OpenSSL 1.0.2k-fips 26 Jan 2017
Erlang processes: 366 used, 1048576 limit
Scheduler run queue: 1
Cluster heartbeat timeout (net_ticktime): 60
Plugins
Enabled plugin file: /usr/local/rabbitmq/rabbitmq_server-3.11.3/etc/rabbitmq/enabled_plugins
Enabled plugins:
* rabbitmq_management
* amqp_client
* rabbitmq_web_dispatch
* cowboy
* cowlib
* rabbitmq_management_agent
Data directory
Node data directory: /usr/local/rabbitmq/rabbitmq_server-3.11.3/var/lib/rabbitmq/mnesia/rabbit@localhost
Raft data directory: /usr/local/rabbitmq/rabbitmq_server-3.11.3/var/lib/rabbitmq/mnesia/rabbit@localhost/quorum/rabbit@localhost
Config files
* /usr/local/rabbitmq/rabbitmq_server-3.11.3/etc/rabbitmq/rabbitmq.conf
Log file(s)
* /usr/local/rabbitmq/rabbitmq_server-3.11.3/var/log/rabbitmq/rabbit@localhost.log
* /usr/local/rabbitmq/rabbitmq_server-3.11.3/var/log/rabbitmq/rabbit@localhost_upgrade.log
* <stdout>
File Descriptors
Total: 2, limit: 927
Sockets: 0, limit: 832
Free Disk Space
Low free disk space watermark: 0.05 gb
Free disk space: 207.3335 gb
Totals
Connection count: 0
Queue count: 0
Virtual host count: 1
Listeners
Interface: [::], port: 15673, protocol: http, purpose: HTTP API
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: 0.0.0.0, port: 5673, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
3.停止
[root@localhost rabbitmq_server-3.11.3]# rabbitmqctl stop
Stopping and halting node rabbit@localhost ...
4.访问web管理系统
本次安装服务器为192.168.11.175,端口配置为 15673,所以访问方式如下
5.账户远程登录
RabbitMQ默认只有一个账户,guest,密码guest,超级管理员角色,但是限制只能本地登录,即localhost 或 127.0.0.1,所以Linux上RabbitMQ远程访问前,需要进行相应账号配置,才能正常登录使用,可以通过以下2种方案
- 将guest账户从回环账户(loopback_users)移除,允许guest账户远程登录。不推荐,因为guest为RabbitMQ默认账户,容易泄露
- 新建账户,配置相应权限,RabbitMQ新建账户默认允许远程登录
关于新建账户,可以通过 rabbitmqctl 命令实现,也可以通过 web 管理系统实现(前提是有远程登录的账户),2种方法都是RabbitMQ启动后使用。
5.1 命令方式示例
#创建账户
[root@localhost rabbitmq_server-3.11.3]# rabbitmqctl add_user admin 123456
Adding user "admin" ...
Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.
#配置角色
[root@localhost rabbitmq_server-3.11.3]# rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...
#配置权限,包括vhost,配置权限如策略,读权限如消费者,写权限如生产者
[root@localhost rabbitmq_server-3.11.3]# rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
Setting permissions for user "admin" in vhost "/" ...
5.2 web管理系统方式,需要先将guest账户移除回环登录限制,然后使用guest远程登录,新建账户后,将guest账户恢复回环登录,或者修改密码,或者直接删除
6.RabbitMQ运行日志路径如下
[root@localhost rabbitmq]# ll /var/log/rabbitmq/
总用量 20
-rw-r-----. 1 rabbitmq rabbitmq 0 12月 10 03:08 rabbit@localhost.log
-rw-r-----. 1 rabbitmq rabbitmq 8936 11月 17 12:37 rabbit@localhost.log-20221120.gz
-rw-r-----. 1 rabbitmq rabbitmq 3427 11月 26 16:50 rabbit@localhost.log-20221128.gz
-rw-r-----. 1 rabbitmq rabbitmq 349 12月 9 23:51 rabbit@localhost.log-20221210.gz
-rw-r-----. 1 rabbitmq rabbitmq 0 11月 16 18:53 rabbit@localhost_upgrade.log
特别关注:系统默认启用了SELinux内核模块(安全子系统),所以在服务绑定/监听某些端口时,提示无访问权限,此时需要禁用SELinux,修改 /etc/selinux/config 文件,设置SELINUX=disabled
Can't start server: Bind on TCP/IP port: Permission denied
特别关注:selinux设置完成需要重启生效,如果当前不方便重启,可以执行 setenforce 0 临时关闭selinux,下次重启是配置再生效
特别关注:系统默认启用了防火墙,请在启动服务前关闭防火墙,或在防火墙中添加服务端口