RabbitMQ 基础知识点介绍

132 阅读10分钟

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: 消息内容和索引全部保存在磁盘中 。