RabbitMq的实践中解决过消息丢失、消息幂等性、消息顺序消费、消息延迟消费等问题;

1、RabbitMq如何实现消息延迟消费?

1.1、延时插件

  答:延时插件 rabbitmq_delayed_message_exchange,下载好之后放到对应plugins目录下,然后启用插件声明交换器类型为 x-delayed-message 来标示此交换机为延时交换机,发送消息时在 header 中添加 x-delay 参数来控制消息的延时时间

1.2、死信队列

  英文缩写DLX,Dead Letter Exchange(死信交换机),当消息成为Dead message(消息过期)后,可以被重新发送到另一个交换机,这个交换机就算是DLX,其实死信交换机(队列)和正常交换机(队列)没有什么区别

1.3、什么情况下消息成为死信队列,消息成为死信队列的三种情况


  1.3.1 队列消息长度达到限制
    比如说给队列最大存储长度为10,当11条消息进来的时候,第11条消息进不去了,那么第11条消息就是死信

  1.3.2 消费者拒绝消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false,
    消费者使用basicNack/basicReject,并且requeue=false,表示消费者拒绝重新消费该消息

  1.3.3 原队列存在消息过期设置,消息到达超时时间未被消费
    原来的队列存在过期时间,但是到了过期时间还没有消费该消息

2、RabbitMq如何保证消息不丢失?

  生产者端:
    1、开启事务(会导致吞吐量下降,太消耗性能)【同步】
    2、开启confirm模式【异步】

  RabbitMq服务端:
    交换机、队列和消息全部设置持久化,当我们MQ挂了之后重启,会从磁盘上恢复queue,恢复队列里的消息

  消费者端:
    关闭自动ACK(消费者收到消息就会自动ACK,可能还没有来得及消费),使用手动ACK(可能存在消费了,没来的及ACK,出现消息再次投递,多次消费情况)

3、产品重复消费原因

  生成者端:
    因网络延迟、超时、RabbitMq服务端宕机、未能正常收到RabbitMq服务端的成功响应值,导致消息重试多次发送

  消费者端:
    和生产者一样,消费者消费了消息,因网络原因,宕机、超时等原因,不能及时返回给RabbitMq服务端成功响应值,导致消息重试多次发送

4、RabbitMq如何保证消息幂等性?

  无论是写入数据库还是写入缓存Redis,给其增加一个唯一主键(唯一key),对于数据库可以判断是否存在该主键,存在则说明消费过。
  对于Redis,的setnx操作就是天然的幂等性,可以根据返回值进行判断

5、RabbitMq如何保证消息顺序性?

  核心思路就是根据业务数据关键值划分成多个消息集合,而且每个消息集合中的消息数据都是有序的,每个消息集合有自己独立的一个consumer。多个消息集合的存在保证了消息消费的效率,每个有序的消息集合对应单个的consumer,也保证了消息消费时的有序性。

  queue里面的消息一定是有序的,只有一个消费者消费queue中的消息,是不会出现消息错乱的。但多个消费者消费同一个queue就会出现消费错乱。

  5.1、一个queue存在多个consumer,不能保证消费者的消费时间顺序,这样也会造成消息消费顺序错误

    将原来的一个queue拆分成多个queue,每个queue都有一个自己的consumer(该种方案的核心是生产者在投递消息的时候根据业务数据关键值(例如订单ID哈希值对订单队列数取模)来将需要保证先后顺序的同一类数据(同一个订单的数据) 发送到同一个queue当中)

  5.2、一个queue对应一个consumer,但是consumer里面进行了多线程消费,这样也会造成消息消费顺序错误

    在consumer中维护多个内存队列,根据业务数据关键值(例如订单ID哈希值对内存队列数取模)将消息加入到不同的内存队列中,然后多个真正负责处理消息的线程去各自对应的内存队列当中获取消息进行消费。
 
posted @ 2024-02-22 09:24  编程小白1024  阅读(223)  评论(0编辑  收藏  举报