一、简介
Messaging that just works — RabbitMQ是一个开源的遵循AMQP
协议实现的基于Erlang语言编写,支持多种客户端(语言),用于在分布式系统中存储消息,转发消息,具有高可用高可扩性,易用性等特征。
二、环境准备(说明)
在官网Linux安装环境说明中Package Dependencies中有此介绍
when installing a local RPM file via yum dependencies must be installed manually. The dependencies are:
- erlang: a supported version of Erlang can be installed from a number of repositories
- socat
- logrotate
因此需要准备环境
erlang:https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-23.2.7-2.el7.x86_64.rpm
Releases · rabbitmq/erlang-rpm · GitHub
Socat:socat 或 yum install -y socat 或 RPM resource socat(x86-64)
logrotate:
rabbitMq:Installing on RPM-based Linux (RedHat Enterprise Linux, CentOS, Fedora, openSUSE) — RabbitMQ
注意:Erlang
和RabbitMQ
版本对照:RabbitMQ Erlang Version Requirements — RabbitMQ
erlang中的el7
表示Red Hat 7.x,即CentOS 7.x 对应操作系统版本
三、安装erlang
1. 创建一个目录将下载好的文件上传到服务器的该目录下
# mkdir -p /usr/lib64/erlang
rz 选择erlang安装包
2.切换到/usr/lib64/erlang
目录,解压安装erlang
# 解压
rpm -Uvh erlang-24.3.4.2-1.el8.x86_64.rpm
# 安装
yum install -y erlang
3.安装完成查看版本号验证
# erl -v
四、安装Socat
1. 使用yum命令安装或者下载安装包后解压缩
# yum install -y socat
2.使用yum命令安装或者下载安装包后解压缩
rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm
五、安装rabbitMq
1.创建目录并将下载好的文件上传到服务器的该目录下
# mkdir -p /usr/lib/rabbitmq
2.切换到/usr/lib/rabbitmq目录并解压缩&安装
# 解压
rpm -Uvh rabbitmq-server-3.10.5-1.el7.noarch.rpm
# 安装
yum install -y rabbitmq-server
3.启动rabbitMq
# 启动rabbitmq
systemctl start rabbitmq-server
# 查看rabbitmq状态
systemctl status rabbitmq-server
显示active
则表示服务安装并启动成功
4.其他命令
# 设置rabbitmq服务开机自启动
systemctl enable rabbitmq-server
# 关闭rabbitmq服务(单节点)
systemctl stop rabbitmq-server
# 重启rabbitmq服务(单节点)
systemctl restart rabbitmq-server
# 启动rabbitmq (单节点)
systemctl start rabbitmq-server
# 查看rabbitmq状态
systemctl status rabbitmq-server
# 集群模式不可直接使用以上停止与启动方法 这样回直接关闭整个集群
#仅关闭应用
rabbitmqctl stop_app
rabbitmqctl start_app
#集群时,启动各个节点,使用 -detached 参数运行各节点
六、RabbitMQWeb管理界面及授权操作
默认情况下,rabbitmq没有安装web端的客户端软件,需要安装才可以生效
# 打开RabbitMQWeb管理界面插件
rabbitmq-plugins enable rabbitmq_management
然后我们打开浏览器,访问服务器ip:15672
(注意打开阿里云安全组以及防火墙的15672端口),就可以看到管理界面
rabbitmq
有一个默认的账号密码guest
,但该情况仅限于本机localhost进行访问,所以需要添加一个远程登录的用户
# 添加用户
rabbitmqctl add_user 用户名 密码
# 设置用户角色,分配操作权限
rabbitmqctl set_user_tags 用户名 角色
# 为用户添加资源权限(授予访问虚拟机根节点的所有权限)
rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*"
#角色有四种:
#administrator:可以登录控制台、查看所有信息、并对rabbitmq进行管理
#monToring:监控者;登录控制台,查看所有信息
#policymaker:策略制定者;登录控制台指定策略
#managment:普通管理员;登录控制
#这里新增eship用户设置密码123456 赋所有权限
rabbitmqctl add_user eship 123456
#添加权限(使admin用户对虚拟主机“/” 具有所有权限):
rabbitmqctl set_permissions -p "/" eship".*" ".*" ".*"
#修改用户角色(加入administrator用户组)
rabbitmqctl set_user_tags admin administrator
创建完成后,访问服务器ip:15672
进行登录,然后便可进入到后台
其他指令:
# 修改密码
rabbitmqctl change_ password 用户名 新密码
# 删除用户
rabbitmqctl delete_user 用户名
# 查看用户清单
rabbitmqctl list_users
7.RabbitMQ集群配置
1.原理介绍
rabbitmq是依据erlang的分布式特性(RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证)来实现的,所以部署rabbitmq分布式集群时要先安装erlang,并把其中一个服务的cookie复制到另外的节点。
abbitmq集群中,各个rabbitmq为对等节点,即每个节点均提供给客户端连接,进行消息的接收和发送。节点分为内存节点和磁盘节点,一般的,均应建立为磁盘节点,为了防止机器重启后的消息消失;
RabbitMQ的Cluster集群模式一般分为两种,普通模式和镜像模式。消息队列通过rabbitmq HA镜像队列进行消息队列实体复制
普通模式下,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈
镜像模式下,将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现RabbitMQ的HA高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在consumer消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。
2.环境介绍及配置
本方案中是在多台机器之间部署rabbitmq的cluster,要求如下:这几个节点需要再同一个局域网内;这几个节点需要有相同的erlang cookie,否则不能正常通信
主机名 | ip |
rabbit1 | 192.168.116.128 |
rabbit2 | 192.168.116.129 |
rabbit3 | 192.168.116.130 |
分别在3台机器上配置/etc/hosts方便集群识别,如下
1 | 192.168.116.128 rabbit1 |
2 | 192.168.116.129 rabbit2 |
3 | 192.168.116.130 rabbit3 |
3.在剩余两台服务器按单机部署方式部署erlang以及rabbitMq
4.设置erlang
在 /var/lib/rabbitmq/目录下 找到 .erlang.cookie 文件
并且将node1赋值到node2 node3 此文件权限为400
chmod 400 /var/lib/rabbitmq/.erlang.cookie
5.各服务器启动 RabbitMQ
rabbitmqctl stop
rabbitmq-server -detached
6.构建集群
# 在rabbit2 节点执行命令 停止并且链接到rabbit1节点
#停止节点
rabbitmqctl stop_app
# 清空节点状态
rabbitmqctl reset
# rabbit2和rabbit1构成集群,rabbit2必须能通过rabbit1的主机名ping通
rabbitmqctl join_cluster rabbit@rabbit1
# 开启rabbitmq服务
rabbitmqctl start_app
# 在rabbit3 节点执行命令 停止并且链接到rabbit1节点
#停止节点
rabbitmqctl stop_app
# 清空节点状态
rabbitmqctl reset
# rabbit3和rabbit1构成集群,rabbit3必须能通过rabbit1的主机名ping通
rabbitmqctl join_cluster rabbit@rabbit1
# 开启rabbitmq服务
rabbitmqctl start_app
#注意:将rabbit2和rabbit3添加到集群当中,并成为磁盘节点,加--ram 参数是内存节点
则此时 rabbit2 与 rabbit3 也会自动建立连接,集群配置完毕;(PS:如果要使用内存节点,则可以使用 rabbitmqctl join_cluster --ram rabbit@rabbit1加入集群)集群配置好后,可以在 RabbitMQ 任意节点上执行 rabbitmqctl cluster_status 来查看是否集群配置成功。
7.将集群设置为镜像模式
只要在其中一台节点执行以下命令:
rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
#设置镜像队列策略的说明
#rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
#-p Vhost: 可选参数,针对指定vhost下的queue进行设置
#Name: policy的名称
#Pattern: queue的匹配模式(正则表达式)
#Definition:镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode
# ha-mode:指明镜像队列的模式,有效值为 all/exactly/nodes
# all:表示在集群中所有的节点上进行镜像
# exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
# nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定
# ha-params:ha-mode模式需要用到的参数
# ha-sync-mode:进行队列中消息的同步方式,有效值为automatic和manual
#priority:可选参数,policy的优先级
8.验证当前集群状态
#执行命令查看
rabbitmqctl cluster_status
web界面验证
打开浏览器,访问服务器ip:15672 登录新建的账号
八、配置SSL
1.生成证书(如果已经有证书可跳过此步骤)
#确保已经安装好openssl
$ git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git
$ cd CMF-AMQP-Configuration/ssl/
# Greyfoss 为自定义的证书签发机构名称(可自行指定),ca目录:用于存储证书颁发机构的信息以及签发的证书
$ sh setup_ca.sh Greyfoss
# 生成服务端证书(公钥和私钥) rabbit-server为生成的密钥前缀 123456为该秘钥自定义的密码
$ sh make_server_cert.sh rabbit-server 123456
# 生成客户端证书(公钥和私钥)
$ sh create_client_cert.sh rabbit-client 123456
#执行完之后 会在ssl目录下生成 ca、server、client 三个文件夹
生成java客户端需要的证书(在java项目中使用)
keytool -import -alias rabbit-server -file server/rabbit-server.cert.pem -keystore server.keystore -storepass 123456
##说明
#import 将已签名数字证书导入密钥库
#alias 指定导入条目的别名
#file 指定要导入的证书
#keystore 指定密钥库的名称
#storepass 指定生成密钥库的密码
####运行该命令会生成密钥库文件server.keystore。
2.配置rabbitMQ
拷贝需要的证书到~/rabbitmq/etc/rabbitmq/ssl
下
$ cp server/rabbit-server.cert.pem ~/rabbitmq/etc/rabbitmq/ssl/
$ cp server/rabbit-server.key.pem ~/rabbitmq/etc/rabbitmq/ssl/
$ cp ca/cacert.pem ~/rabbitmq/etc/rabbitmq/ssl/
编辑~/rabbitmq/etc/rabbitmq/rabbitmq.conf
文件,替换为以下内容:
rabbitMQ.config需要从官网下载:rabbitmq-server/rabbitmq.conf.example at main · rabbitmq/rabbitmq-server · GitHub
管理端页面配置:Management Plugin — RabbitMQ
# 禁用非tls连接
#listeners.tcp = none
# SSL\TLS通信的端口
listeners.ssl.default = 5671
# 管理控制台端口
management.tcp.port = 15672
# 服务端私钥和证书文件配置
ssl_options.cacertfile = /etc/rabbitmq/ssl/cacert.pem
ssl_options.certfile = /etc/rabbitmq/ssl/rabbit-server.cert.pem
ssl_options.keyfile = /etc/rabbitmq/ssl/rabbit-server.key.pem
# 有verify_none和verify_peer两个选项,verify_none表示完全忽略验证证书的结果,verify_peer表示要求验证对方证书
ssl_options.verify = verify_peer
# 若为true,服务端会向客户端索要证书,若客户端无证书则中止SSL握手;若为false,则客户端没有证书时依然可完成SSL握手
ssl_options.fail_if_no_peer_cert = false
# 指定开启的tls版本
ssl_options.versions.1=tlsv1.2
ssl_options.versions.2=tlsv1.1
# 指定对应的cipher suites
ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
ssl_options.ciphers.3 = ECDHE-ECDSA-AES256-SHA384
ssl_options.ciphers.4 = ECDHE-RSA-AES256-SHA384
ssl_options.ciphers.5 = ECDHE-ECDSA-DES-CBC3-SHA
ssl_options.ciphers.6 = ECDH-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.7 = ECDH-RSA-AES256-GCM-SHA384
ssl_options.ciphers.8 = ECDH-ECDSA-AES256-SHA384
ssl_options.ciphers.9 = ECDH-RSA-AES256-SHA384
ssl_options.ciphers.10 = DHE-DSS-AES256-GCM-SHA384
ssl_options.ciphers.11= DHE-DSS-AES256-SHA256
ssl_options.ciphers.12 = AES256-GCM-SHA384
ssl_options.ciphers.13 = AES256-SHA256
ssl_options.ciphers.14 = ECDHE-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.15 = ECDHE-RSA-AES128-GCM-SHA256
ssl_options.ciphers.16 = ECDHE-ECDSA-AES128-SHA256
ssl_options.ciphers.17 = ECDHE-RSA-AES128-SHA256
ssl_options.ciphers.18 = ECDH-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.19= ECDH-RSA-AES128-GCM-SHA256
ssl_options.ciphers.20 = ECDH-ECDSA-AES128-SHA256
ssl_options.ciphers.21 = ECDH-RSA-AES128-SHA256
ssl_options.ciphers.22 = DHE-DSS-AES128-GCM-SHA256
ssl_options.ciphers.23 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.24 = AES128-GCM-SHA256
ssl_options.ciphers.25 = AES128-SHA256
ssl_options.ciphers.26 = ECDHE-ECDSA-AES256-SHA
ssl_options.ciphers.27 = ECDHE-RSA-AES256-SHA
ssl_options.ciphers.28 = DHE-DSS-AES256-SHA
ssl_options.ciphers.29 = ECDH-ECDSA-AES256-SHA
ssl_options.ciphers.30 = ECDH-RSA-AES256-SHA
ssl_options.ciphers.31= AES256-SHA
ssl_options.ciphers.32 = ECDHE-ECDSA-AES128-SHA
ssl_options.ciphers.33 = ECDHE-RSA-AES128-SHA
ssl_options.ciphers.34 = DHE-DSS-AES128-SHA
ssl_options.ciphers.35 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.36 = ECDH-ECDSA-AES128-SHA
ssl_options.ciphers.37 = ECDH-RSA-AES128-SHA
ssl_options.ciphers.38 = AES128-SHA
3.重启rabbitMQ
4.验证 查看是否开启
看到amqp/ssl 5671
说明配置成功!
5.SpringBoot集成RabbitMQ SSL
首先在配置文件中添加以下配置,比如在application-dev.yaml
中添加:
spring:
rabbitmq:
virtual-host: /
host: 127.0.0.1
port: 5671
username: ${RABBIT_USERNAME}
password: ${RABBIT_PASSWORD}
ssl:
enabled: true
key-store: classpath:keyStore/rabbit-client.keycert.p12
key-store-password: ${KEYSTORE_PASSWORD}
trust-store: classpath:keyStore/server.keystore
trust-store-password: ${TRUSTSTORE_PASSWORD}
algorithm: TLSv1.2
verify-hostname: false
导入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
九、RabbitMQ其他相关
1.rabbitMQ用户权限
TAG权限:
(1) 超级管理员(administrator)
可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。
(2)监控者(monitoring)
可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
(3) 策略制定者(policymaker)
可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)
(4) 普通管理者(management)
仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。
(5) 其他(None)
无法登陆管理控制台,通常就是普通的生产者和消费者。
2.RabbitMQ的工作模式
RabbitMQ的工作模式,RabbitMQ共五种工作模式:
简单模式:就是一个生产者一个消费者,中间通过一个队列直接连接。
work工作模式:就是有多个消费者消费队列里的消息,队列里的消息只能被一个消费者消费。
这样多部署几个消费者,就可以缓解压力,比如过年的时候抢票,抢票成功后会给你发短信,这个时候就可以把发短信的任务放入队列里,然后有多个发短信的服务来处理队列里的任务。
(其他场景:抢红包,抢票等)
pub/sub发布订阅模式:上面两种模式生产者的消息只能被一个消费者消费,不符合某些实际场景。
需要用到一个Exchange交换机角色来帮助我们把消息发给所有订阅我们的服务商。每个消费者都能消费一整套完整的消息。
Routing路由模式:路由模式就是交换机并不是给所有订阅他的队列发送消息了,
而是根据路由键来确定应该给哪个队列发送消息,队列和交换机绑定的时候需要通过路由键,而生产者发送消息的时候也需要指定路由键,这样就可以确定给哪个队列发送消息了。
Topics主题模式:主题模式就相当于模糊匹配,假如我想给姓张的发送消息,那么我就可以通过主题模式给所有姓张的发送消息。
Classic 经典队列,
Quorum 仲裁队列,
Stream 队列
RabbitMQ在3.9版本引入了一种新的队列类型Stream Queue,它与当前的 Classic(经典) 队列不同,消息被消费后不会被自动删除,像Kafka一样,消息会继续驻留在队列中。当一个队列需要被多个应用系统(的消费者)订阅时,以往的方式,总是使用fanout类型的exchange,将消息广播到多个队列中,每个队列对应一个应用系统(的消费者)。而Stream队列打破了这种方式,一个队列可以被多个应用系统(的消费者)反复使用。“反复”的意思不仅是指它能同时被多个应用系统(的消费者)访问,也是指消费者可以从队列的任意位置开始访问消息。消费者只要指定"x-stream-offset"参数,就可以回到队列的指定位置,好像按了重播按钮一样,重新消费数据。
RabbitMQ队列解析:rabbitmq进阶:整体理解、编程模型和高级特性_天黑请闭眼丶风的博客-CSDN博客_rabbitmq编程