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协议,强一致性


好了今天就到这里

相关推荐
少云清2 小时前
【性能测试】4_Locust _locust分布式
分布式·性能测试·locust
Mr Aokey2 小时前
RabbitMQ进阶实战:三种典型消息路由模式详解(订阅/路由/主题)
java·网络·rabbitmq
zhangxl-jc2 小时前
SparkStreaming消费Kafka 重启任务时重复消费数据
分布式·spark·kafka
xiaolyuh1232 小时前
Kafka、RocketMQ、RabbitMQ 事务消息核心差异对比
kafka·rabbitmq·rocketmq
天天进步201513 小时前
多线程与分布式:使用 Botasaurus 轻松构建大规模数据采集集群
分布式·爬虫
一点事14 小时前
windows:安装rabbitMQ
windows·rabbitmq·ruby
川西胖墩墩17 小时前
复杂任务的分布式智能解决方案
人工智能·分布式
小北方城市网19 小时前
MySQL 索引优化实战:从慢查询到高性能
数据库·spring boot·后端·mysql·rabbitmq·mybatis·java-rabbitmq
2501_9418053120 小时前
使用Python和Go构建高性能分布式任务调度系统的实践分享
分布式·python·golang