在面试的过程之中,假设你在简历当中填写了mq的相关技术,那面试官大概率会考察这方面的问题来看看你对mq相关知识的掌握程度,小编在这一块也被拷打过,今天就和大家一起来了解一下这方面的知识,希望大家都有所提升。
1.消息队列当中消息的丢失问题
在一整个消息队列当中,一般来说会出现三种消息的丢失场景:
1.首先是生产者在将消息传输到broker服务器当中会出现消息丢失,这可能是出现网络波动又或者是服务器发生了宕机。
2.同时服务器broker出现消息持久化时也会出现消息丢失,一般是由于消息队列没有及时存储并完成持久化,比如服务器宕机或者重启,消息都会发生丢失。
3.消费者往broker当中拉取消息时也会出现消息的丢失问题。这可能是由于,消费者获取消息的过程出现网络波动导致消息获取失败,也可能是消费者拿到消息后没能正常消费或者是消费者出现处理异常或消费者出现宕机。
对于消息的丢失问题,消息队列一共给出了三种解决方案:
1.Confirm消息确认机制(生产者)
Confirm机制可以说是消息队列提供的一种消息可靠性保障机制,当生产者发送消息到服务器时,会等待服务器确认,当消息正确投递到queue时会返回ack,假设没有正确投递到queue会返回nack,但假设消息没有进行正确绑定queue,就会出现消息丢失的问题。
**使用方法:**生产者通过confirm.select方法将Channel设置为Confirm模式,而发送消息后,就会通过添加add_confirm_listener方法监听消息的确认状态。
2.消息持久化机制(Mq服务器)
持久化机制是指将消息存储到磁盘,来保证服务器重启或者宕机后,消息不会丢失。
**使用方法:**生产者通过将消息的delivery_mode属性值设置为2,后将消息标记为持久化,同时队列也需要进行持久化的设置,经典队列需要将durable的值设置为true,但是仲裁队列和流式队列默认必须持久化保存。
不过持久化机制势必会影响系统的性能,所以需要在确保消息不丢失的场景下去使用。
3.ACK事务机制(消费者)
ACK事务机制用于确保消息被正确的消费,当消息被消费者成功处理之后,消费者会发送确认(ACK)给消息对列,告知消息可以被移除。
**使用方法:**ACK的消费机制是默认开启的。当消息被消费者接收之后,会立刻从队列当中删除,除非消费者发生了异常。ACK机制也可以手动开启,将auto_ack的参数设置为False来手动控制消息的ACK。
2.消息队列当中消息的重复消费问题
消息队列的消息重复消费的问题是十分常见的,接下来我们来讲解一个情景,假设有两个消费者分别是消费者A和消费者B,消息首次交给消费者A进行消费,此时消费者A成功将消息消费完并记录到数据库当中,但由于回调ACK确认时由于网络波动的原因导致超时了,那消息队列就会默认这条消息没有被成功消费,而是重新投递给了新的消费者B去处理,这样就会出现重复消费的问题。
而为了解决这一方面的问题,实际上就是要保证消费端的幂等性,这在不同的业务当中实现方式是不同的,假设上一段所举得列子是一个订单的操作,那就可以把订单号拼接成一个uuid,并在数据库设计成唯一索引,这样其他的消费者收到已经消费后的消息,就会发现后台数据库已经存在这样的订单id,这样就能有效避免重复消费的问题,也可以使用 redis 将消费过的消息唯一标识存储起来,然后在消费端业务执行之前判断 redis 中是否已经存在这个标识。
今天的分享就到这里了,希望这篇博客能给你一些帮助,让你对关于保证消息队列当中的消息丢失、重复的问题得到进一步的提升,在面试的时候能从容面对面试官。