一、rabbitmq介绍
1、rabbitmq简介
RabbitMQ是一个开源的消息代理和队列服务器,它用于通过轻量且可靠的消息在服务器之间进行通信。RabbitMQ实现了高级消息队列协议(AMQP),这一协议最初由摩根大通牵头设计,随后被多家公司采纳并推广。作为AMQP协议的开源实现,RabbitMQ可以跨多种语言和平台使用,如Java、.NET、Ruby、PHP、Python、JavaScript等,支持几乎所有的消息队列和发布/订阅场景。
2、RabbitMQ 的一些重要组成部分和特性的详细介绍:
- 可靠性:RabbitMQ通过持久化消息和队列来确保消息的可靠性,即使在网络分区或服务器故障的情况下也能保证消息不丢失。同时,它还支持消息的确认机制,确保消息被正确处理和消费。
- 灵活性:RabbitMQ支持多种消息传递模式,包括点对点(P2P)、发布/订阅(Pub/Sub)、路由(Routing)和主题(Topics)。这使得RabbitMQ能够满足各种复杂的消息传递需求。
- 可扩展性:RabbitMQ支持集群功能,可以通过添加更多的节点来扩展消息处理能力。这使得RabbitMQ能够处理大量的并发请求和高吞吐量的场景。
- 易用性:RabbitMQ提供了丰富的管理界面和API,方便用户对队列、交换机、绑定等进行配置和管理。同时,它还提供了多种语言的客户端库,使得开发者可以方便地集成RabbitMQ到他们的应用中
- 安全性:RabbitMQ支持多种认证机制,如用户名/密码、TLS/SSL加密等,确保消息传递的安全性。
- 插件系统:RabbitMQ 提供了丰富的插件系统,允许用户根据自己的需求扩展和定制功能,例如通过 SSL 加密传输、使用不同的身份验证方式等。
- 消息队列:RabbitMQ 使用消息队列来存储和传递消息。消息队列通过先进先出(FIFO)的方式处理消息,允许生产者将消息发送到队列,然后消费者从队列中接收这些消息。
- 生产者:生产者是发送消息到 RabbitMQ 交换机的应用程序。生产者将消息发布到特定的交换机,并且可以选择将消息发送到特定的队列或交换机。
- 交换机:交换机是 RabbitMQ 接收生产者消息并路由到相应队列的组件。它根据指定的规则(路由键)将消息发送到一个或多个绑定的队列。
- 队列:队列是 RabbitMQ 中消息的目的地。生产者通过交换机将消息发送到队列,而消费者从队列中接收消息以进行处理。
- 消费者:消费者是从 RabbitMQ 队列中获取消息并对其进行处理的应用程序。消费者订阅一个或多个队列,并接收队列中的消息。
- 路由:RabbitMQ 使用路由机制将消息从交换机路由到队列。这是通过在交换机和队列之间建立绑定关系,并使用路由键来匹配消息。
- ACK 机制:RabbitMQ 提供了 ACK(确认)机制,确保消息被正确处理。一旦消费者接收到并处理了消息,它可以发送一个 ACK 给 RabbitMQ,告知消息已被处理。如果消费者在处理消息过程中发生故障或崩溃,RabbitMQ 将重新传递未确认的消息给其他消费者。
3、RabbitMQ与Kafka的区别
1****)、数据处理模型:
RabbitMQ:RabbitMQ 是一个传统的消息队列中间件,采用的是面向消息的数据处理模型。它接收、存储和转发消息,并使用AMQP等协议提供可靠的消息传递机制。
Kafka:Kafka 是一个高吞吐量的分布式流数据平台,采用发布-订阅模型。它以持久化并分区的方式存储消息,并支持批量读写,适用于大规模实时数据流处理场景。
2****)、数据保留时间:
RabbitMQ:RabbitMQ 默认情况下不会保留消息,即使消费者没有接收到消息,也不会在消息队列中保留太长时间。
Kafka:Kafka 保留所有的消息,并根据配置的时间保留策略(例如时间段或消息大小)决定消息在存储中的保留时间。
3****)功能特性:
RabbitMQ:RabbitMQ 提供高级消息队列协议(AMQP)的完整实现,并且支持多种交换机类型、消息确认、消息持久化、消息优先级等功能。它还有广泛的插件生态系统可供扩展。
Kafka:Kafka 提供高吞吐量的消息传递,保证消息的可靠性和持久化存储。它支持流处理功能,具有日志存储和批量消费的特点。
4****)扩展性和可靠性:
RabbitMQ:RabbitMQ 以队列为基本单位,并使用内存来管理消息,在高负载情况下可能会出现性能瓶颈。
Kafka:Kafka 具有良好的水平伸缩性,可以通过添加更多的节点来提高吞吐量和容错性。它使用磁盘文件存储消息,可以大规模地处理海
协议与定位:
RabbitMQ是AMQP(高级消息队列协议)的标准实现,以broker代理为中心,支持解耦、异步、削峰限流等功能。它提供了消息的确认机制,确保消息的可靠性。
Kafka是Apache的一个开源项目,是一个分布式发布订阅消息系统。它以consumer为中心,没有消息确认机制,但采用了独特的设计以提供高吞吐量和容错性。
5****)消息处理与顺序:
RabbitMQ在处理消息时,并不特别强调顺序性。
Kafka则能够保证顺序处理消息,这在某些对消息顺序有严格要求的场景下是非常有用的。
6****)批量处理与吞吐量:
RabbitMQ支持事务,但不支持批量操作,因此其吞吐量相对较小。
Kafka内部消息可以进行批量处理,这使得其消息处理效率高,吞吐量高,特别适用于大数据场景。
7****)负载均衡:
RabbitMQ不支持负载均衡,需要依赖外部的loadbalance支持。
Kafka则采用zK来协调负载均衡问题,通过轮询的方式发送消息到broker上,实现负载均衡。
8****)路由与过滤:
RabbitMQ在消息路由和过滤方面提供了更好的支持,这对于复杂的消息传递场景是非常有用的。
9****)容错处理:
RabbitMQ提供了诸如交付重试和死信交换器(DLX)来处理消息处理故障。
Kafka没有提供这种开箱即用的机制,需要在应用层提供和实现消息的重试机制。
4、RabbitMQ与Kafka的各自适用场景
1****)RabbitMQ适用场景:
可靠性:RabbitMQ强调消息的可靠性传递,支持事务和持久化等机制,适用于需要确保每条消息都能被准确处理的场景。它适合于任务队列、工作流、订单处理等需要精确控制消息交付和顺序的应用。
灵活的路由:RabbitMQ提供了灵活的路由机制,通过交换机和绑定规则将消息路由到特定的队列,适合处理复杂的消息路由需求。
多语言支持:RabbitMQ提供了多种客户端库,支持多种编程语言,便于不同语言环境下的开发和集成。
2****)Kafka适用场景:
高吞吐量:Kafka注重高吞吐量和低延迟,适合处理大量数据流和日志类型的应用。它具备非常高的读写能力,能够同时处理大量的实时数据流。
持久性存储:Kafka将消息以日志形式持久化到磁盘,可支持长时间存储数据,可以用作数据源和数据传输中间件,适合构建实时流处理和事件驱动的应用。
分布式架构:Kafka具备分布式、可扩展的特性,支持水平扩展、副本集群和故障容错等功能,适合大规模分布式系统和多节点集群环境。
5、AMQP协议
AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。AMQP协议的主要特征包括面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全等。在AMQP协议中,定义了四种对象:Publisher(发布者)、Consumer(消费者)、Exchange(交换机)和Queue(队列)。Publisher产生消息,Consumer接收消息,Exchange将Publisher产生的消息通过规则转发到队列,而Queue则存储着即将被Consumer获取的消息。
AMQP协议的主要目标是提供一个通用的消息传递框架,以便不同的应用程序可以在不同的平台上进行通信。它规定了在网络上传输的数据的格式,以字节为流,任何遵守此数据格式的工具都能与其他兼容工具进行互操作。这意味着,基于AMQP协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品、不同的开发语言等条件的限制。
此外,AMQP协议还定义了一套丰富的安全机制,包括身份认证、访问控制和消息加密。通过这些安全机制,可以确保消息的机密性、完整性和可用性,保护系统免受恶意攻击和非法访问。
AMQP (Advanced Message Queuing Protocol) 是一个提供统一消息服务的应用层通讯协议,为消息中间件提供统一的开发规范。不同客户端可以将消息投递到中间件上,或从上面获取消息;发送消息和接收消息的客户端可以采用不同的语言开发、不同的技术实现,但必须遵循相同的 AMQP 协议。AMQP 协议本身包括以下三层:
Module Layer:位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。例如:可以使用 Queue.Declare 命令声明一个队列或者使用 Basic.Consume 订阅消费一个队列中的消息。
Session Layer:位于中间层,主要负责将客户端的命令发送给服务器,再将服务端的应答返回给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理。
Transport Layer:位于最底层,主要传输二进制数据流 ,提供帧的处理、信道复用、错误检测和数据表示等。
二、RabbitMQ的安装
由于RabbitMQ是基于Erlang(面向高并发的语言)语言开发,所以在安装RabbitMQ之前,需要先安装Erlang。
1、安装Erlang
[root@ligc_3 ~]#wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-22.3.4.12-1.el7.x86_64.rpm/download.rpm
[root@ligc_3 ~]#yum -y localinstall erlang-22.3.4.12-1.el7.x86_64.rpm
2、RabbitMQ下载安装
1)下载rabbitmq****安装包
下载地址****https://github.com/rabbitmq/rabbitmq-server/tags
[root@ligc_3 ~]# mkdir -p /apps/rabbitMQ/
[root@ligc_3 ~]#cd /apps/rabbitMQ/
[root@ligc_3 ~]# wget --content-disposition https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.13-1.el7.noarch.rpm/download.rpm
2)导入rabbitmq密钥
[root@ligc_3 ~]#rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
3)安装rabbitmq
[root@ligc_3 ~]#yum -y localinstall rabbitmq-server-3.8.13-1.el7.noarch.rpm
4)RabbotMQ的启动
[root@ligc_3 ~]#systemctl start rabbitmq-server #启动
[root@ligc_3 ~]#systemctl enable rabbitmq-server #设置开机自启
[root@ligc_3 ~]#systemctl status rabbitmq-server #查看状态
3、RabbitMQ Web界面管理
默认情况下,是没有安装web端的客户端插件,需要安装插件才可以生效。执行命令:
[root@ligc_3 ~]#rabbitmq-plugins enable rabbitmq_managemen
然后需要重启服务
[root@ligc_3 ~]#systemctl restart rabbitmq-server
三、Web界面访问管理
RabbitMQ 默认的管理界面账号和密码通常是:
- 用户名:guest
- 密码:guest
这对默认凭据在 RabbitMQ 安装后可用于访问管理界面(只限于本地)。然而,出于安全考虑,强烈建议在生产环境中修改默认凭据或创建新的管理员帐户,并使用更强大的密码来加强安全性。
要在 RabbitMQ 中添加新用户,您需要使用 RabbitMQ 提供的命令行工具或者管理界面进行操作。下面是两种方法的简要说明:
方法一:使用** RabbitMQ **命令行工具
1****、运行以下命令来添加新用户:
[root@ligc_3 ~]#rabbitmqctl add_user <username> <password>
将 <username> 替换为要创建的用户名,将 <password> 替换为所需的密码。
2****、运行以下命令来赋予用户管理员权限:
[root@ligc_3 ~]#rabbitmqctl set_user_tags <username> administrator
将
<username>
替换为刚创建的用户名。
方法二:使用** RabbitMQ **管理界面
- 打开您的浏览器并访问 RabbitMQ 管理界面。默认地址为 http://192.168.10.114:15672。
2、使用默认的管理员账号和密码(通常是 guest/guest)登录到管理界面。
3、在管理界面上导航到 “Admin” -> “Users” 选项卡。
4、单击 “Add a user” 按钮。
5、输入用户名和密码,并选择 “Tag” 为 “Administrator”。
6、单击 “Add user” 按钮以创建新用户。
四、集群搭建
1、RabbitMQ的集群架构
RabbitMQ的集群架构主要可以分为以下几种:
- 主备模式:也被称为“warren”或“兔子窝”模式。在这种模式下,存在一个主节点和一个或多个备节点。当主节点出现故障时,备节点会接管服务,继续对外提供服务。这种模式类似于ActiveMQ利用Zookeeper实现的主备方案,但RabbitMQ通常使用HaProxy进行路由。当主节点恢复后,它会变成备节点的备份节点,实现热备份。主节点通常负责对外提供读写服务,而备节点则作为备份存在。
- 远程模式:即Shovel模式,这种模式主要用于远距离通信和复制,实现双活的一种模式。它的配置相对复杂,但在某些场景下,如互联网大厂中,它的使用频率较高。
- 镜像模式:在这种模式下,队列会在多个节点之间进行镜像,以实现高可用性和数据同步。当某个节点出现故障时,其他节点可以继续提供服务,确保消息的可靠性。
- 多活模式:这是实现异地数据复制的主流模式。与Shovel模式相比,多活模式更为简单,因此在实际应用中更为常见。它依赖于RabbitMQ的federation插件来实现持续的AMQP数据通信。
上图是,非常经典的 mirror 镜像模式,保证 100% 数据不丢失。在实际工作中也是用得最多的,并且实现非常的简单,一般互联网大厂都会构建这种镜像集群模式。
mirror 镜像队列,目的是为了保证 rabbitMQ 数据的高可靠性解决方案,主要就是实现数据的同步,一般来讲是2 - 3个节点实现数据同步。对于100%数据可靠性解决方案,一般是采用 3 个节点。
如上图所示,用 KeepAlived 做了 HA-Proxy 的高可用,然后有 3 个节点的 MQ 服务,消息发送到主节点上,主节点通过 mirror 队列把数据同步到其他的MQ节点,这样来实现其高可靠。
这就是RabbitMQ整个镜像模式的集群架构。
RabbitMQ集群搭建步骤
◆设置主机名或host,使得节点之间可以通过名称访问
◆安装RabbitMQ单节点
◆复制Erlang cookie
◆启动RabbitMQ并组成集群
2、环境搭建
1****)创建三台虚拟机
虚拟机名
IP
主从划分
Ligc_1
192.168.10.112
从节点
Ligc_2
192.168.10.113
从节点
Ligc_3
192.168.10.114
主节点
2****)配置三台主机通过主机名访问:
[root@ligc_3 ~]# vim /etc/hosts
192.168.10.112 ligc_1
192.168.10.113 ligc_2
192.168.10.114 ligc_3
[root@ligc_3 ~]# scp /etc/hosts 192.168.10.112:/etc/hosts
[root@ligc_3 ~]# scp /etc/hosts 192.168.10.113:/etc/hosts
- 在3台机器上分别安装rabbitmq,安装好后都先停掉rabbitmq server
1)安装Erlang
[root@ligc_3 ~]#wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-22.3.4.12-1.el7.x86_64.rpm/download.rpm
[root@ligc_3 ~]#yum -y localinstall erlang-22.3.4.12-1.el7.x86_64.rpm
2)下载rabbitmq****安装包
下载地址****https://github.com/rabbitmq/rabbitmq-server/tags
[root@ligc_1 ~]# mkdir -p /apps/rabbitMQ/
[root@ligc_1 ~]#cd /apps/rabbitMQ/
[root@ligc_1 ~]# wget --content-disposition https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.13-1.el7.noarch.rpm/download.rpm
3)导入rabbitmq密钥
[root@ligc_1 ~]#rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
4)安装rabbitmq
[root@ligc_1 ~]#yum -y localinstall rabbitmq-server-3.8.13-1.el7.noarch.rpm
**5)、RabbotMQ启动后关闭 **
[root@ligc_1 ~]#systemctl start rabbitmq-server #启动
[root@ligc_1 ~]#systemctl enable rabbitmq-server #设置开机自启
[root@ligc_1 ~]#systemctl status rabbitmq-server #查看状态
[root@ligc_1 ~]#systemctl stop rabbitmq-server #关闭服务
3、同步cookie文件
选择任意一个rabbitmq节点作为master,复制该节点的的cookie文件到其它rabbitmq节点上,这里选择ligc_3主机为master
1)需要停掉服务器的rabbitMQ的服务(如果没有停掉的话,Erlang的cookie是再被占用的)
[root@ligc_3 ~]#systemctl stop rabbitmq-server
2)修改.erlang.cookie权限
[root@ligc_3 ~]#cat /var/lib/rabbitmq/.erlang.cookie
[root@ligc_3 ~]#chmod 777 /var/lib/rabbitmq/.erlang.cookie
3)将主节点的.erlang.cookie文件传输至集群所有节点
[root@ligc_3 ~]#scp /var/lib/rabbitmq/.erlang.cookie 192.168.10.112:/var/lib/rabbitmq/
[root@ligc_3 ~]#scp /var/lib/rabbitmq/.erlang.cookie 192.168.10.113:/var/lib/rabbitmq/
4)复原.erlang.cookie权限
[root@ligc_3 ~]#chmod 400 /var/lib/rabbitmq/.erlang.cookie
4、加入集群
1****)所有节点启动rabbitmq
[root@ligc_3 ~]#** systemctl start rabbitmq-server **
2****)在非主节点上执行以下命令
[root@ligc_1 ~]#rabbitmqctl stop_app # 1.关闭RabbitMQ服务
[root@ligc_1 ~]#rabbitmqctl reset # 2.重置节点
[root@ligc_1 ~]# rabbitmqctl join_cluster rabbit@ligc_3
3.节点加入, 在一个node加入cluster之前,必须先停止该node的rabbitmq应用,即先执行stop_app
[root@ligc_1 ~]# rabbitmqctl start_app # 4.启动服务
加入节点、重置节点注意:
我们首先将 rabbit@hello-TQ2与rabbit@hello_TQ1 加入一个集群。为此,我们要在 rabbit@hello-TQ2与rabbit@hello_TQ1 上停止 RabbitMQ 应用程序并加入 rabbit@VM-24-15-centos(node1节点) 群集,然后重新启动 node2、node3的RabbitMQ 应用程序。
请注意,节点必须重置后才能加入现有群集。重置节点会删除该节点上以前存在的所有资源和数据。这意味着,节点不能在成为群集成员的同时保留其现有数据。如果需要这样做,可以使用蓝/绿部署策略或备份和还原。
** 5、查看集群状态(命令查看)**
通过在任一节点上运行
rabbitmqctl cluster_status
命令,我们可以看到这两个节点已加入集群中:
[root@ligc_1 ~]# rabbitmqctl cluster_status
6、 解除集群节点
如果想解除node3(rabbit@hello_TQ1):
首先,在node3机器上做如下操作,命令如下:
[root@ligc_1 ~]# rabbitmqctl stop_app # 关闭rabbitMQ服务
然后,在node1上做忘记node3节点的操作,如下:
[root@ligc_3 ~]# rabbitmqctl forget_cluster_node rabbit@ligc_1
操作此命令之前,一定要先关闭被忘记的节点的服务,否则,如下错误:
根据提示,可知,上面两步操作可以都在node1上完成,直接先stop,再forget,如下:
[root@ligc_3 ~]#rabbitmqctl -n rabbit@hello-TQ2 stop_app
[root@ligc_3 ~]#rabbitmqctl forget_cluster_node rabbit@hello-TQ2
** 五、镜像队列**
- 普通模式集群存在的问题
1.1 演示问题——不能备份
上面集群虽然可以启动自动集群发现机制,但是存在的问题是,如果创建队列(发送消息)的rabbitmq服务宕机了,消息就丢失了,
1.2 引入镜像队列
RabbitMQ的自动集群发现机制可以帮助集群中的Exchange和Queue自动地分布到所有节点上,从而提高系统的可用性和可伸缩性。然而,这种机制并不能完全保证消息的高可用性。如果某个节点出现故障,该节点上的Exchange和Queue可能会丢失或不可用,从而导致消息丢失或无法传递。为了解决这个问题,RabbitMQ提供了镜像队列(Mirrored Queue)的功能。
2、 配置镜像队列
.2.1、指定复制系数配置策略
如果你的集群有很多节点,那么此时复制的性能开销就比较大,此时需要选择合适的复制系数。通常可以遵循过半写原则,即对于一个节点数为 n 的集群,只需要同步到 n/2+1 个节点上即可。此时需要同时修改镜像策略为 exactly,并指定复制系数 ha-params。
使用set_ policy 命令设置镜像队列策略
rabbitmqctl set_ policy [-p Vhost] Name Pattern Definition [Priority]
rabbitmqctl set_ policy Vhost 策咯名称 正则表达式 策略定义 优先级
Definition:策略定义
**ha-mode:**指明镜像队列的模式
all:表示在集群中所有的节点上进行镜像
exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
**nodes:**表示在指定的节点上进行镜像,节点名称通过ha-params指定
** ha-params: **ha-mode模式需要用到的参数
**ha-svnc-mode:**进行队列中消息的同步方式,有效值为automatic和manual
设置镜像队列策略案例:
◆ 匹配所有队列,并将镜像配置到集群中的所有节点
rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:“all”}’
◆ 名称以"two"开始的队列镜像到群集中的任意两个节点
rabbitmqctl set_policy ha-two “^two.” ‘{“ha-mode” :" exactly" ,“ha-params”:2,“ha-sync-mode”:" automatic}’
◆ 以" node"开头的队列镜像到集群中的特定节点
rabbitmqctl set_policy ha-nodes “^ nodes.” ‘{“ha-mode”:" nodes" ,“ha-params” :[“rabbit@nodeA”, “rabbit@nodeB”]}’
在任意一个节点上执行
某个节点接收到消息,会自动同步到其它节点。镜像模式并没有严格的主从节点之分,任何节点都可以接受、处理消息。
版权归原作者 zero_open 所有, 如有侵权,请联系我们删除。