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安装
本文按照单实例模式,二进制方式安装。
组件安装操作步骤参考 组件安装部署手册模板,根据不同组件的安装目标,部分操作可以省略。
本文将按照该参考步骤执行。
一、获取组件可执行程序库,包括主程序,此为组件的基本文件
1.官网下载 RabbitMQ二进制安装包,保存 /usr/local/rabbitmq 目录
也可以直接在GitHub ReleaseNote下直接查找下载
2.安装依赖组件
2.1 下载Erlang,保存 /usr/local/erlang/src 目录
根据RabbitMQ与Erlang版本依赖,我们选择Erlang 25.1,通过Erlang官网下载获取
2.2 安装Erlang编译依赖工具
[root@localhost src]# yum install -y build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz
2.3 Erlang编译依赖JDK 1.6及以上版本,安装教程参考
- Java JDK安装 - OracleJDK(CentOS 7 + OracleJDK 8u201)
- Java JDK安装 - AdoptOpenJDK(CentOS 7 + AdoptOpenJDK 8)
2.4 解压编译安装Erlang
[root@localhost src]# ls otp_src_25.1.tar.gz [root@localhost src]# tar -zxvf otp_src_25.1.tar.gz [root@localhost src]# cd otp_src_25.1 [root@localhost otp_src_25.1]# ls AUTHORS configure erlang_ls.config HOWTO make otp_patch_apply plt system bin configure.src erl-build-tool-vars.sh lib Makefile.in OTP_VERSION prebuilt.files TAR.include bootstrap CONTRIBUTING.md erts LICENSE.txt otp_build otp_versions.table README.md xcomp [root@localhost otp_src_25.1]# ./configure --prefix=/usr/local/erlang/ [root@localhost otp_src_25.1]# make -j 4 && make install
2.5 配置Erlang环境变量,验证Erlang版本
[root@localhost otp_src_25.1]# vim /etc/profile #erlang export ERLANG_HOME=/usr/local/erlang export PATH=$PATH:$ERLANG_HOME/bin [root@localhost otp_src_25.1]# source /etc/profile [root@localhost otp_src_25.1]# erl Erlang/OTP 25 [erts-13.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] Eshell V13.1 (abort with ^G)
特别关注
其他很多教程提示需要安装 socat 组件,但本次安装过程中,并没有相关提示,原因暂时没有排查,请根据实际情况安装
3.RabbitMQ解压安装
[root@localhost rabbitmq]# ls rabbitmq-server-generic-unix-3.11.3.tar.xz [root@localhost rabbitmq]# tar -xvf rabbitmq-server-generic-unix-3.11.3.tar.xz [root@localhost rabbitmq_server-3.11.3]# ls escript LICENSE-BSD-base64js LICENSE-MIT-Flot LICENSE-MPL-RabbitMQ etc LICENSE-BSD-recon LICENSE-MIT-jQuery LICENSE-rabbitmq_aws INSTALL LICENSE-erlcloud LICENSE-MIT-jQuery164 plugins LICENSE LICENSE-httpc_aws LICENSE-MIT-Mochi sbin LICENSE-APACHE2 LICENSE-ISC-cowboy LICENSE-MIT-Sammy share LICENSE-APACHE2-excanvas LICENSE-MIT-EJS LICENSE-MIT-Sammy060 var LICENSE-APACHE2-ExplorerCanvas LICENSE-MIT-EJS10 LICENSE-MPL LICENSE-APL2-Stomp-Websocket LICENSE-MIT-Erlware-Commons LICENSE-MPL2
二、安装系统服务
RabbitMQ二进制安装方式,默认没有安装系统服务,通过主程序运行。
三、主程序加入到环境变量
1.将RabbitMQ目录添加到环境变量
[root@localhost bin]# vim /etc/profile #rabbitmq export RABBITMQ_HOME=/usr/local/rabbitmq/rabbitmq_server-3.11.3 export PATH=$PATH:$RABBITMQ_HOME/sbin [root@localhost bin]# source /etc/profile
四、配置文件
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,下次重启是配置再生效
特别关注:系统默认启用了防火墙,请在启动服务前关闭防火墙,或在防火墙中添加服务端口