RabbitMQ如何确保消息的可靠性

mq的消息可靠性的确保分为三个方面:生产方、mq服务、消费方。
一、生产方:开启应答机制。
1.生产者发送消息后,编写ConfirmCallback回调函数(局部)
- 消息成功到达交换机后,返回发送者ACK
- 消息如果未到达交换机,返回发送者NACK
- 消息超时未发送成功会抛出异常
2.消息到达交换机后,如果未能到达队列,也会导致消息丢失,生产者编写ReturnCallback回调函数(全局)
- 消息到达交换机,未到达队列,RabbitMQ会调用ReturnCallback通知发送者,告知失败原因
二、MQ服务:RabbitMQ提供了持久化功能,集群的主从备份功能
- 消息持久化,RabbitMQ会将交换机、队列、消息持久化到磁盘,可以通过配置类和注解实现(默认开启)
- 镜像集群,仲裁队列,都可以提供主从备份功能,主节点宕机,从节点会自动切换为主,数据依然在
三、消费方: 开启应答机制
1.消费方有三种消费确认机制,默认采用auto模式(出现异常,返回nack;为出现异常,返回ack)。消费者 处理失败时,消息重新入队,再次发送。此模式下,消息频繁入队会影响服务性能
2.为避免了消息频繁入队带来的额外压力,Spring提供的消费者重试机制,则是在处理失败后不返回NACK, 而是直接在消费者本地重试(设置三个参数:初始等待时间、失败等待时长倍数、最大重试次数)
3.默认情况下,消息重试达到最大重试次数,消息将被丢弃。为改善此情况,Spring提供了Republish策略, 在多次重试都失败,耗尽重试次数后,将消息重新投递给指定的异常交换机,携带异常信息后续交人工处理

MQ消费消息的过程

  • 生产者生成消息,将消息转发的exchange交换机
  • 交换机将消息转发的队列中
  • 消费者写监听器,根据绑定的队列和交换机,从队列中消费消息

    RabbitMQ如何避免消息堆积

    原因:原因往往是因为消息发送的速度超过了消费者消息处理的速度。
    - 提高消费者处理速度
    - 增加更多消费者
    - 增加队列消息存储上限
    - 惰性队列

    如果真的消息堆积如何处理?

    设置一个过期时间,如果消息过期就可以删除让其他消息加入到对列中

    如果删除的消息是有用的怎么解决?

    只能等过了高峰期以后将数据一点点查询出来然后批量重新导入到mq中

    RabbitMQ如何保证消息的有序性

  • 保证消息发送的有序性
    - 保证一组有序的消息都发送到同一个队列
    - 保证一个队列只包含一个消费者

    如何防止MQ消息被重复消费

    就是保证项目的幂等性:

    1.使用数据库中的唯一约束
    例如主键id,因为唯一约束是一张表的唯一标识,是不允许重复的
    2.Redis
    redis的key值不能重复,有这个key值就代表已经消费
    3.记录表
    保存时生成一个唯一标记,把该标记保存到记录表
    4.分布式锁
    通过redisson的AtimicLong来实现。

    如何保证RabbitMQ的高可用

  • 做好交换机、队列、消息的持久化
    - 普通集群、镜像集群、仲裁队列
    - 搭建RabbitMQ的镜像集群,做好主从备份。当然也可以使用仲裁队列代替镜像集群

    使用MQ可以解决那些问题

    解耦合 流量削峰 延迟队列