RabbitMQ篇

大家好我是小明,今天学习消息中间件RabbitMQ


`

文章目录

  • [1. RabbbitMQ如何保证消息不丢失问题(最高频)](#1. RabbbitMQ如何保证消息不丢失问题(最高频))
  • [2. RabbitMQ消息的重复消费如何解决??](#2. RabbitMQ消息的重复消费如何解决??)
  • [3. RabbitMQ中的死信交换机(RabbitMQ延迟队列有了解过吗?)](#3. RabbitMQ中的死信交换机(RabbitMQ延迟队列有了解过吗?))
  • [4. RabbitMQ如果有100万条消息堆积在MQ,如何解决(信息堆积怎么解决)](#4. RabbitMQ如果有100万条消息堆积在MQ,如何解决(信息堆积怎么解决))
  • [5. RabbitMQ的高可用机制有哪些有了解过吗。](#5. RabbitMQ的高可用机制有哪些有了解过吗。)

复习大纲


1. RabbbitMQ如何保证消息不丢失问题(最高频)

这个这么回答:

生产者确认机制: 消息发到MQ后会返回一个ack给生产者,表示消息成功发送到mq.
消费者确认机制: 消费者处理完消息后发送ack给MQ,MQ收到ack回执后,MQ才会删除该消息。

SpringAMQP则允许配置三种消费者消息确认确认模式:

  1. 自动确认: RabbitMQ 会⾃动把发送出去的消息置为确认, 然后从内存(或者磁盘)中删除, ⽽不管消费者是否真正地消费到了这些消息.
  2. 手动确认: 费者处理完业务后,手动调用 channel.basicAck() 确认;处理失败则调用 basicNack()/basicReject() 拒绝(可重入队列或丢弃)。
  3. 批量确认(批量手动) : 就是消费者处理完一批消息之后就确认这一批消息,下面看批量确认代码
java 复制代码
// 批量确认示例(假设累计处理100条后确认)
private int batchCount = 0;
private long lastDeliveryTag = 0;

@RabbitListener(queues = "batch.queue")
public void onBatchMessage(Message message, Channel channel) throws IOException {
    long deliveryTag = message.getMessageProperties().getDeliveryTag();
    try {
        // 处理业务逻辑
        processMessage(message);
        batchCount++;
        lastDeliveryTag = deliveryTag;
        // 累计100条批量确认
        if (batchCount >= 100) {
            channel.basicAck(lastDeliveryTag, true); // 确认所有<=lastDeliveryTag的消息
            batchCount = 0; // 重置计数器
        }
    } catch (Exception e) {
        // 批量处理失败,拒绝当前消息并停止批量
        channel.basicNack(deliveryTag, false, true);
        batchCount = 0;
    }
}

假如说:消费者消息确认失败怎么办

可以利用Spring的retry机制,在消费者出现异常时利用本地重试机制,设置重试次数,当到达一定次数还是失败,就把消息丢到死信队列,由人工处理。

消息持久化: MQ默认是内存存储消息,开启持久化可以保证消息在MQ中消息不丢失。

面试回答:


2. RabbitMQ消息的重复消费如何解决??

问题:

消费者处理完消息之后,发送的ack用于网络波动没有接收到,mq再次发送该消息给消费者处理,导致消费者重复消费。

解决: 消息带身份标识(id,支付id,订单id),消费者校验该id是否存在进行处理,如果存在直接跳过处理流程。


3. RabbitMQ中的死信交换机(RabbitMQ延迟队列有了解过吗?)

死信出现的三种情况?

  1. 消息被拒绝(Rejected):消费者调用了 basicReject 或 basicNack 方法并且方法的第二个参数 requeue(重入队列)被设置为 false,
  2. 消息过期(TTL Expired):队列设置了过期时间: 整个队列里的所有消息都有统一的过期时间(x-message-ttl)。消息本身设置了过期时间: 发送消息时给这条消息单独设置了过期时间(expiration 属性)。
  3. 队列达到最大长度:队列像一个桶,桶满了,再往里面倒水,水就会溢出来。溢出的消息就会变成死信。

延迟队列: 进入队列的消息会被延迟消费的队列

使用场景:

  • 30 分钟内支付订单
  • 定时发布作品
  • 限时优惠
    延迟队列的实现原理(TTL + 死信队列)
  1. 创建一个 "延迟队列"(实际是普通队列),不给它配置消费者(消息不会被立即消费);
  2. 给这个延迟队列设置 TTL(消息过期时间),并绑定死信交换机;
  3. 消息发送到这个延迟队列后,会在队列里 "等待" 直到过期;
  4. 消息过期后,会自动变成死信,被转发到绑定的死信交换机;
  5. 死信交换机再把消息路由到实际消费队列,消费者监听这个队列,就能拿到 "延迟后的消息"。

简单来说:延迟队列的本质是 "让消息先在一个'临时队列'里等过期,过期后自动转到消费队列被处理",TTL + 死信是实现这个逻辑的 "巧劲"。


4. RabbitMQ如果有100万条消息堆积在MQ,如何解决(信息堆积怎么解决)

当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。

解决消息堆积三种思路:

  • 增加更多消费者,提高消费速度
  • 在消费者内开启线程池加快消息的消息的处理速度
  • 扩大队列容积,提高堆积上线

这么扩大队列消息容积呢??

惰性队列

设置队列属性为lazy该队列就会变成惰性队列。

  • 消息存储在硬盘中而非内存。
  • 消费者需要消费消息时才会从磁盘中读取并加载。
  • 支持数百万消息存储。

这样就扩大消息的存储了。


5. RabbitMQ的高可用机制有哪些有了解过吗。

镜像集群

本质: 主从模式

具备以下特征:

  • 交换机,队列,队列中的消息在各个MQ节点的镜像节点进行同步。

  • 创建队列的节点被称为队列主节点,备份到的节点叫做队列的进镜像点。

  • 一个队列的主节点可能是另一个队列的镜像节点。

  • 所有操作都是由主节点完成,然后同步镜像节点。

  • 主节点宕机后,镜像节点会代替成新主节点,主节点在数据同步时宕机的会造成数据丢失

    仲裁队列

  • 和镜像队列一样,都是主从模式,支持主从数据同步

  • 使用非常简单,没有复杂的配置

  • **主从同步使用Raft协议,强一致性


好了今天就到这里

相关推荐
014-code10 小时前
Dubbo 之 “最速传说”
java·分布式·dubbo
LF3_10 小时前
监听数据库binlog日志变化,将变动实时发送到kafka
数据库·分布式·mysql·kafka·binlog·debezium
闲猫10 小时前
企业级分布式系统运维全栈指南
分布式
渔民小镇10 小时前
告别 Redis/MQ —— ionet 分布式事件总线实战
java·服务器·分布式
智算菩萨10 小时前
与AI一起记忆:从分布式记忆到AI策划记忆与人机共忆——文献精读
论文阅读·人工智能·分布式·深度学习·ai·文献
珠海西格10 小时前
4 月 1 日起执行分布式光伏监控新规,直接影响从业者与项目收益
大数据·运维·服务器·分布式·能源
中议视控11 小时前
会议室和展厅分布式网络中控系统主机的选购思路
网络·分布式
发际线还在1 天前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
chikaaa1 天前
RabbitMQ 核心机制总结笔记
java·笔记·rabbitmq·java-rabbitmq
Francek Chen1 天前
【大数据存储与管理】分布式数据库HBase:05 HBase运行机制
大数据·数据库·hadoop·分布式·hdfs·hbase