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就会出现消费错乱。