RabbitMQ消息队列


1.为什么使用MQ?

使用MQ的场景很多,主要有三个:解耦、异步、削峰。

  • 解耦:假设现在,日志不光要插入到数据库里,还要在硬盘中增加文件类型的日志,同时,一些关 键日志还要通过邮件的方式发送给指定的人。那么,如果按照原来的逻辑,A可能就需要在原来的 代码上做扩展,除了B服务,还要加上日志文件的存储和日志邮件的发送。但是,如果你使用了MQ,那么,A服务是不需要做更改的,它还是将消息放到MQ中即可,其它的服务,无论是原来的B服务还是新增的日志文件存储服务或日志邮件发送服务,都直接从MQ中获取消息并处理即可。 这就是解耦,它的好处是提高系统灵活性,扩展性。
  • 异步:可以将一些非核心流程,如日志,短信,邮件等,通过MQ的方式异步去处理。这样做的好 处是缩短主流程的响应时间,提升用户体验。
  • 削峰:MQ的本质就是业务的排队。所以,面对突然到来的高并发,MQ也可以不用慌忙,先排好 队,不要着急,一个一个来。削峰的好处就是避免高并发压垮系统的关键组件,如某个核心服务或 数据库等。

2.消息队列的缺点

1.系统可用性降低

系统引入的外部依赖越多,越容易挂掉。

2、系统复杂度提高

加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。

3、 一致性问题

A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,这就数据不一致了。

3.Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

image-20230226192006231

  • 中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;
  • 大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
  • 大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,几乎是全世界这个领域的事实 性规范。

RabbitMQ

1.RabbitMQ是什么?

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。

RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。

2.RabbitMQ特点?

  • 可靠性: RabbitMQ使用一些机制来保证可靠性, 如持久化、传输确认及发布确认等。
  • 灵活的路由 : 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能, RabbitMQ 己经提 供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个 交换器绑定在一起, 也可以通过插 件机制来实现自己的交换器。
  • 扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态地扩展 集群中节点。
  • 高可用性 : 队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队 列仍然可用。
  • 多种协议: RabbitMQ除了原生支持AMQP协议,还支持STOMP, MQTT等多种消息中间件协议。
  • 多语言客户端:RabbitMQ 几乎支持所有常用语言,比如 Java、 Python、 Ruby、 PHP、 C#、 JavaScript 等。
  • 管理界面 : RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集 群中的节点等。
  • 令插件机制: RabbitMQ 提供了许多插件 , 以实现从多方面进行扩展,当然也可以编写自 己的插件。

3.AMQP是什么?

RabbitMQ就是 AMQP 协议的 Erlang 的实现(当然 RabbitMQ 还支持 STOMP2 、 MQTT3 等协议 ) AMQP 的模型架构 和 RabbitMQ 的模型架构是一样的,生产者将消息发送给交换器,交换器和队列绑 定 。

RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。 目前 RabbitMQ 最新版本默认支持的是 AMQP 0-9-1。

4.AMQP的3层协议?

  • Module Layer:协议最高层,主要定义了一些客户端调用的命令,客户端可以用这些命令实现自己的业 务逻辑。

  • Session Layer:中间层,主要负责客户端命令发送给服务器,再将服务端应答返回客户端,提供可靠性同 步机制和错误处理。

  • TransportLayer:最底层,主要传输二进制数据流,提供帧的处理、信道服用、错误检测和数据表示等。

5.说说Broker服务节点、Queue队列、Exchange交换器?

  • Broker可以看做RabbitMQ的服务节点。一般请下一个Broker可以看做一个RabbitMQ服务器。

  • Queue:RabbitMQ的内部对象,用于存储消息。多个消费者可以订阅同一队列,这时队列中的消息 会被平摊(轮询)给多个消费者进行处理。

  • Exchange:生产者将消息发送到交换器,由交换器将消息路由到一个或者多个队列中。当路由不到 时,或返回给生产者或直接丢弃。

6.如何保证消息的可靠性?

  • 生产者到RabbitMQ:事务机制和Confirm机制,注意:事务机制和 Confirm 机制是互斥的,两者 不能共存,会导致 RabbitMQ 报错。

  • RabbitMQ自身:持久化、集群、普通模式、镜像模式。

  • RabbitMQ到消费者:basicAck机制、死信队列、消息补偿机制。

7.生产者消息运转的流程?

\1. Producer 先连接到Broker,建立连接Connection,开启一个信道(Channel)。

\2. Producer 声明一个交换器并设置好相关属性。

\3. Producer 声明一个队列并设置好相关属性。

\4. Producer 通过路由键将交换器和队列绑定起来。

\5. Producer 发送消息到 Broker ,其中包含路由键、交换器等信息。

\6. 相应的交换器根据接收到的路由键查找匹配的队列。

\7. 如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。

\8. 关闭信道。

\9. 管理连接。

8.消费者接收消息过程?

\1. Producer 先连接到 Broker ,建立连接 Connection ,开启一个信道( Channel )。

\2. 向 Broker 请求消费响应的队列中消息,可能会设置响应的回调函数。

\3. 等待 Broker 回应并投递相应队列中的消息,接收消息。

\4. 消费者确认收到的消息, ack 。

\5. RabbitMq 从队列中删除已经确定的消息。

\6. 关闭信道。

\7. 关闭连接。

9.生产者如何将消息可靠投递到RabbitMQ?

\1. Client发送消息给MQ

\2. MQ将消息持久化后,发送Ack消息给Client,此处有可能因为网络问题导致Ack消息无法发送到Client,那么Client在等待超时后,会重传消息;

\3. Client收到Ack消息后,认为消息已经投递成功。

10.RabbitMQ如何将消息可靠投递到消费者?

\1. MQ将消息push给Client(或Client来pull消息)

\2. Client得到消息并做完业务逻辑

\3. Client发送Ack消息给MQ,通知MQ删除该消息,此处有可能因为网络问题导致Ack失败,那么Client会重复消息,这里就引出消费幂等的问题;

\4. MQ将已消费的消息删除。

11.如何保证RabbitMQ消息队列的高可用?

RabbitMQ 有三种模式:单机模式普通集群模式镜像集群模式

  • 单机模式:就是demo级别的,一般就是你本地启动了玩玩儿的,没人生产用单机模式

  • 普通集群模式:意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。

  • 镜像集群模式:这种模式,才是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据(元数据指RabbitMQ的配置数据)还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。

RocketMQ


  目录