RabbitMQ基础

目录

RabbitMQ的可靠性投递

[确保消息正确地发送至 RabbitMQ](#确保消息正确地发送至 RabbitMQ)

确保消息接收方消费了消息

流程分析

1.生产者发送消息给Broker

2.交换机路由消息到队列

3.消息存储在队列

4.消费者订阅并消费消息

三个重要概念

RabbitMQ集群模式


RabbitMQ的可靠性投递

在 RabbitMQ 中,确保消息正确地发送和消息接收方消费消息通常需要采取一些措施。

确保消息正确地发送至 RabbitMQ
  1. 生产者确认:RabbitMQ 支持生产者确认机制,即发布确认(Publisher Confirms)。通过启用生产者确认,生产者可以等待 RabbitMQ 确认消息已成功接收并存储,然后再继续发送下一条消息。

  2. 消息持久性:在发布消息时,确保消息被标记为持久性(persistent)。这意味着消息将被保存到磁盘,即使 RabbitMQ 服务器重启,消息也不会丢失。

  3. 交换机和队列的持久性:确保交换机和队列也被标记为持久性,以防止它们在 RabbitMQ 服务器重启时丢失。

  4. 备份交换机:使用备份交换机(Alternate Exchange)来确保消息在无法路由到目标队列时不会丢失。备份交换机将无法路由的消息路由到备份队列,以供后续处理。

确保消息接收方消费了消息
  1. 消费者确认:在消费者端,您可以使用消费者确认来确保消息已被正确处理。RabbitMQ 支持基本确认模式,消费者可以发送确认给 RabbitMQ,告知它已成功接收和处理消息。如果消费者未发送确认,消息将被重新排队,确保不会丢失。

  2. 消息应答模式:RabbitMQ 支持两种消息应答模式,分为自动应答和手动应答。在手动应答模式下,消费者必须明确发送应答以告知 RabbitMQ 消息已被处理。这提供了更大的控制力和可靠性,因为只有在确认消息处理后才会发送应答。

  3. 消息持久性:如果消费者接收到消息后,将其处理并将结果写入数据库或其他持久性存储,可以确保消息被持久化。这样即使消费者故障,可以在重新启动后重新处理消息。

  4. 幂等性处理:消费者应该实现幂等性处理,以确保多次处理相同消息的效果与一次处理相同消息的效果相同。这样即使消息重复传递,也不会引起问题。

流程分析

1.生产者发送消息给Broker
  • 怎么知道消息发送成功了?

    RabbitMQ 里面提供了两种服务端确认机制进行应答,告知生产者是否发送成功

    • Transaction(事务)模式

      通过一个 channel.txSelect()的方法把信道设置成事务模式,当Broker回复Producer一个Ack(Commit-OK指令)后,才能提交成功。同步阻塞的方式缺点也很明显:需要等待,消耗性能,不建议生产使用。

    • Confirm(确认)模式(总共有三种)

      将信道设置成 confirm 模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的 ID。 一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一 ID),发送方确认模式通常选择异步的。

      • 普通确认模式:发一条确认一条->缺点就是有点慢

      • 批量确认模式:发一批,没异常默认都接收了->缺点是一批是多少?怎么衡量?

      • 异步确认模式:生产者应用程序在等待确认的同时,可以继续发送消 息。

  • 怎么避免消息重复投递或重复消费?

    • 在消息生产时:MQ 内部针对每条生产者发送的消息生成一个 inner-msg-id,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列。

    • 在消息消费时:要求消息体中必须要有一个 bizId(对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,避免同一条消息被重复消费。

  • 消息基于什么传输?

    由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶 颈。RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的 虚拟连接,且每条 TCP 连接上的信道数量没有限制。

2.交换机路由消息到队列
  • 怎么处理消息无法正确路由到队列?

    1. 消息回发的方式:服务端重发给生产者,提供错误码告知路由失败消息。

    2. 消息路由到备份交换机的方式:在创建交换机的时候,指定备份交换机存放以备后续处理。

3.消息存储在队列
  • 没有消费者消费的情况下,队列存储在自身数据库,怎么防止异常情况下(重启、宕机 、关闭等)导致内存中的消息丢失?

    队列持久化、交换机持久化、消息持久化、使用集群多个节点同步备份。

  • 怎么分发消息给消费者?

    若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消 费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。

4.消费者订阅并消费消息
  • 怎么确认接收成功?

    消费者确认机制:自动或手动发送Ack给服务端。Ack设置的三个值:NONE(自动Ack)、MANUAL(手动Ack)、AUTO(没异常就发送Ack)。

三个重要概念

在 RabbitMQ 中,消息的幂等性、顺序性和最终一致性是消息处理的重要概念,用于确保消息系统的可靠性和正确性。

1. 消息的幂等性(Message Idempotence)

  • 概念:消息的幂等性是指无论消息被处理多少次,其效果都与一次处理的效果相同。即使消息重复传递,也不会引发不一致性或错误结果。

  • 实现:为实现消息的幂等性,生产者和消费者可以采用以下方法:

    • 在生产者端为每个消息分配唯一的消息标识符(Message ID),并在消费者端维护已经处理过的消息 ID 列表。在处理消息前,消费者可以检查消息 ID 是否已经存在于列表中,如果存在则不处理。

2. 消息的顺序性(Message Ordering)

  • 概念:消息的顺序性要求消息在传递和处理时保持特定的顺序,即消息按照其发送的顺序进行处理。

  • 实现:RabbitMQ 本身保证单个队列内消息的顺序性,但在分布式系统中,全局顺序性可能更为复杂。为实现全局顺序性,可以采用以下方法:

    • 使用单一队列:将所有相关消息发送到单一队列,这样可以确保它们按顺序处理。

    • 基于分区键(Partition Key):将消息根据某个关键属性(如订单号)分发到不同的队列或分区,然后在消费者端将它们重新排序。

3. 消息的最终一致性(Message Eventually Consistency)

  • 概念:最终一致性指的是在分布式系统中,即使系统出现故障或网络延迟,最终数据仍然达到一致性状态。

  • 实现:实现最终一致性需要以下策略:

    • 异步确认:在消息处理完成后,异步发送确认,即使消费者端出现故障,消息系统也可以在稍后重新传递消息。

    • 消息持久性:将消息和数据持久化,以确保即使系统重启,消息不会丢失。

    • 冗余:使用多个副本以增加系统的可用性和冗余。

综合考虑这些概念,RabbitMQ 中的消息可以通过确保消息的幂等性、维护顺序性和实现最终一致性来处理。这些概念和实现方法可以帮助设计和构建可靠的消息传递系统。

RabbitMQ集群模式

集群主要用于实现高可用与负载均衡。

  • 高可用:如果集群中的某些 MQ 服务器不可用,客户端还可以连接到其他MQ服务器。
  • 负载均衡:在高并发的场景下,单台 MQ 服务器能处理的消息有限,可以分发给多台 MQ 服务器。

RabbitMQ 有两种集群模式:普通集群模式和镜像队列模式。

  • 普通集群模式下,不同的节点之间只会相互同步元数据。普通集群模式不能保证队列的高可用性,因为队列内容不会复制。如果节点失效将导致相关队列不可用,因此我们需要第二种集群模式。

  • 镜像队列模式下,消息内容会在镜像节点间同步,可用性更高。不过也有一定的副作用,系统性能会降低,节点过多的情况下同步的代价比较大。

相关推荐
用户8307196840822 小时前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者1 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者3 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧4 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖4 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农4 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者4 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀4 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3054 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05094 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式