1.什么是RabbitMQ?
RabbitMQ 是一款开源的消息队列(Message Queue, MQ)中间件,基于 AMQP(高级消息队列协议) 开发,使用 Erlang 语言实现。它通过消息的异步传输和分发机制,帮助分布式系统实现解耦、异步处理和流量控制,广泛应用于微服务架构、事件驱动系统、日志处理等场景。
2.RabbitMQ特点?
(1) 轻量级与易用性
-
低资源消耗:RabbitMQ 对服务器资源的需求较低,适合中小企业的轻量级部署。
-
开箱即用:安装和配置简单,Docker 镜像部署仅需几条命令即可完成。
-
社区活跃:丰富的文档和教程,遇到问题时可快速找到解决方案(如 CSDN、知乎等平台的案例支持)。
-
易用管理界面 : RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集 群中的节点等。
-
支持多种协议: RabbitMQ除了原生支持AMQP协议,还支持STOMP, MQTT等多种消息 中间件协议。
-
支持多语言客户端 :RabbitMQ 几乎支持所有常用语言,比如 Java、 Python、 Ruby、 PHP、 C#、 JavaScript 等。
(2) 高可靠性与稳定性
- 消息不丢失:通过持久化、确认机制和镜像队列,确保消息在传输和处理过程中不丢失。
- 故障恢复:支持集群部署和队列镜像,即使部分节点故障,系统仍能正常运行。
- 成熟度高:自 2007 年推出以来,RabbitMQ 经过多年迭代和验证,在金融、电商等领域有广泛应用案例。
(3) 灵活的路由与扩展性
- 多样化路由策略:支持多种交换器类型,满足复杂的业务场景需求(如订单处理、日志分发等)。
- 插件化扩展:通过插件(如 LDAP 认证、联邦队列)可灵活扩展功能,适应不同企业的定制化需求。
(4)成本效益
- 免费开源:中小企业无需支付商业授权费用,降低了技术选型成本。
- 低运维成本:轻量级架构和简单的部署方式减少了运维复杂性,适合技术团队规模有限的企业。
3.RabbitMQ适用场景?
- 微服务架构:通过消息队列实现服务间解耦,提升系统的可维护性和可扩展性。
- 异步任务处理:如邮件发送、图片处理等耗时操作,通过队列异步执行,提高响应速度。
- 流量削峰:在秒杀、促销等高并发场景下,通过队列缓冲请求,避免后端服务过载。
- 事件驱动架构:基于发布/订阅模式实现事件通知(如订单状态变更、支付成功通知)。
4.生产者Producer?
生产者是指生成并发送消息的应用程序或服务。它创建消息并将它们发送到消息队列系统中的某个交换器(Exchange)。 生产者的任务是产生数据,并确保这些数据能够被正确地传递给消息队列系统。
消息通常包含两大部分:消息体(Body)和消息属性(Properties)。
- 消息体:这是消息的实际内容,可以是任何形式的数据,例如文本、JSON 或者二进制数据等。
- 消息属性:这些是与消息相关的元数据,比如内容类型、编码方式、优先级、持久化标志等。
5.消费者Consumer?
消费者是从队列中接收并处理消息的应用程序或服务。一旦消息被放置在队列中,消费者可以连接到该队列,并获取消息进行处理。 消费者负责执行与收到的消息相关的逻辑操作。
6.Broker服务节点?
在MQ 中,Broker 服务节点指的是运行消息代理软件的单个实例或服务器。这些节点负责管理消息的存储、转发和处理,是分布式系统中实现异步通信的核心组件。
7.Queue队列?
队列用于存储消息,位于消息队列系统内部。它是消费者获取消息的地点。每个消息都会被放置在一个或多个队列中,直到被消费者取出处理。 队列遵循先进先出(FIFO, First In First Out)原则,除非特别配置了其他的行为。
8.Exchange交换器?
交换器是生产者发送消息的第一站。它不直接存储消息,而是根据一定的规则将消息路由到一个或多个队列中。RabbitMQ 支持多种类型的交换器,包括 Direct、Fanout、Topic 和 Headers,每种类型都有不同的消息路由策略。
- Direct:通过精确匹配路由键(Routing Key)来决定消息路由到哪个队列。
- Fanout:广播消息到所有绑定的队列,忽略路由键。
- Topic:允许使用通配符模式匹配路由键进行灵活的消息路由。
- Headers:基于消息头属性而非路由键来进行路由选择。
Exchange:生产者将消息发送到交换器,有交换器将消息路由到一个或者多个队列中。当路由不到时,或返回给生产者或直接丢弃。
9.RoutingKey路由键?
生产者将消息发送给交换器的时候,会指定一个RoutingKey,用来指定这个消息的路由规则,这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。
10.Binding绑定?
通过绑定将交换器和队列关联起来,一般会指定一个BindingKey,这样RabbitMq就知道如何正确路由消息到队列了。
11.交换器的4种类型?
主要有以下4种:
- Direct:通过精确匹配路由键(Routing Key)来决定消息路由到哪个队列。
- Fanout:广播消息到所有绑定的队列,忽略路由键。
- Topic:允许使用通配符模式匹配路由键进行灵活的消息路由。
- Headers:基于消息头属性而非路由键来进行路由选择。性能差,基本用不到。
12.生产者如何进行消息运转?
1.Producer先连接到Broker,建立连接Connection,开启一个信道(Channel)。
2.Producer声明一个交换器并设置好相关属性。
3.Producer声明一个队列并设置好相关属性。
4.Producer通过路由键将交换器和队列绑定起来。
5.Producer发送消息到Broker,其中包含路由键、交换器等信息。
6.相应的交换器根据接收到的路由键查找匹配的队列。
7.如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。
8.关闭信道。
9.管理连接。
13.消费者接收消息过程?
1.Cosumer先连接到Broker,建立连接Connection,开启一个信道(Channel)。
2.向Broker请求消费响应的队列中消息,可能会设置响应的回调函数。
3.等待Broker回应并投递相应队列中的消息,接收消息。
4.消费者确认收到的消息,ack。
5.RabbitMq从队列中删除已经确定的消息。
6.关闭信道。
7.关闭连接。
14.交换器无法根据自身类型和路由键找到符合条件队列时,有哪些处理?
在 RabbitMQ 中,当 交换器(Exchange) 无法根据自身类型和 路由键(Routing Key) 找到符合条件的队列时,消息的处理方式取决于生产者设置的 mandatory 参数。
1. mandatory: true(消息返回给生产者)
-
行为:如果交换器无法将消息路由到任何队列(例如没有绑定的队列或绑定规则不匹配),消息会被 返回给生产者。
-
适用场景:
- 需要确保消息不丢失,生产者可以重新处理或记录失败原因。
- 例如,业务关键性高,必须保证消息被正确消费。
-
实现方式:
生产者需监听basic_return回调函数,接收未被路由的消息。
示例代码(Python):python 深色版本 def on_return(ch, method, props, body): print(f"Message returned: {body.decode()}") channel.add_on_return_callback(on_return) channel.basic_publish( exchange='my_exchange', routing_key='invalid_key', body='Test Message', mandatory=True # 必须设置为 True )
2. mandatory: false(消息直接丢弃)
-
行为:如果交换器无法将消息路由到任何队列,消息会被 直接丢弃。
-
适用场景:
- 允许消息丢失,且不需要生产者处理失败情况(例如日志广播、低优先级任务)。
- 降低系统资源消耗(无需返回未路由消息)。
-
实现方式:
生产者不设置mandatory参数或显式设置为False。
示例代码(Python):python 深色版本 channel.basic_publish( exchange='my_exchange', routing_key='invalid_key', body='Test Message', mandatory=False # 或不设置此参数 )
15.消费者获取消息的方式?
- 推
- 拉
16.消费者某些原因无法处理当前接受的消息如何来拒绝?
- channel .basicNack :拒绝批量消息
- channel .basicReject : 拒绝单条消息
17.死信队列?
DLX,全称为 Dead-Letter-Exchange,死信交换器。当消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称之为死信队列。
18.导致的死信的几种原因?
- 消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false。
- 消息TTL过期。
- 队列满了,无法再添加。
19.延迟队列?
延迟队列(Delayed Queue) 是一种特殊类型的消息队列,其核心特点是:队列中的消息在指定的时间之后才能被消费者获取和处理。与普通队列(先进先出,FIFO)不同,延迟队列的消息会按照预设的延迟时间排序,只有当消息的延迟时间到达时,消费者才能取出并处理它
20.什么是优先级队列?
优先级队列(Priority Queue) 是一种特殊的队列数据结构,其核心特点是:元素的出队顺序由优先级决定,而非入队顺序。优先级高的元素会优先被处理,即使它在队列中是后入队的。与普通队列(先进先出,FIFO)不同,优先级队列通过动态排序确保高效的任务调度。
RabbitMQ 通过 x-max-priority 参数设置队列优先级,消费者按优先级消费消息。
当消费速度大于生产速度且Broker没有堆积的情况下,优先级显得没有意义。
21.什么是发送确认机制?
发送确认机制(Publisher Confirm) 是 RabbitMQ 提供的一种保障消息从 生产者到 Exchange 可靠性传递的机制。它的核心目标是确保消息成功投递到 RabbitMQ 服务器的 Exchange,而不是直接丢弃或因网络问题丢失。
生产者发送消息后,RabbitMQ 会返回一个 确认(ACK) 或 否定确认(NACK) ,告知生产者消息是否成功到达 Exchange。
发送确认流程:
- 生产者调用
channel.confirmSelect(),声明启用 Confirm 机制。 - RabbitMQ 会为每个 Channel 维护一个 事务缓冲区,缓存待确认的消息。
- 消息通过
basic.publish发送到 Exchange。 - 若 Exchange 存在且消息写入成功,RabbitMQ 会异步返回 ACK;否则返回 NACK。
- 若收到 ACK,消息已成功到达 Exchange。
- 若收到 NACK,需重发消息或记录错误日志。
23.消息传输保证层级?
At most once:最多一次。消息可能会丢失,单不会重复传输。
At least once:最少一次。消息觉不会丢失,但可能会重复传输。
Exactly once: 恰好一次,每条消息肯定仅传输一次。
24.什么是vhost?
每一个RabbitMQ服务器都能创建虚拟的消息服务器,也叫虚拟主机(virtual host),简称vhost。
默认为“/”。
25.RabbitMQ中消息可能有的几种状态?
alpha: 消息内容(包括消息体、属性和 headers) 和消息索引全部存储在内存中 。
beta: 消息内容 保存在磁盘中,消息索引 保存在内存中。
gamma: 消息内容保存在磁盘中,消息索引同时保存在磁盘和内存中 。
delta: 消息内容和索引全部保存在磁盘中 。