没用过消息中间件,是如何忽悠面试官的?

Posted 程序员读书俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没用过消息中间件,是如何忽悠面试官的?相关的知识,希望对你有一定的参考价值。





简介

消息中间件也是最近面试的常客,不管你用过没用过,使用过程中有没有遇到面试官提及的问题,总不能一问三不知,他尴尬你也尴尬。本文针对常见的中间件面试问题做一个总结,只是为了应对面试,写的没那么深刻。但总算给大家提出了关键问题的解决思路,更像是一个大纲。有不明白的地方请发到留言区,我们深入探讨,可开小灶。

话不多说,我们先看看为什么要有消息中间件。

  • 异步处理

  • 应用解耦

  • 削峰

虽然消息中间件有诸多好处,但是也带来了一些问题。比如

  • 可用性、如何保证消息队列的高可用

  • 复杂性

  • 一致性问题,是指产生消息的业务动作与消息发送的一致,如果业务操作成功了,那么对应的消息一定要发送出去,否则就丢失消息。同理消息业务失败也不应该把消息发送出去。

如何处理消息丢失的问题?

消息丢失可能出现在生产者、mq、消费者。下面以RabbitMQ举例。

  1. 在生产者给mq发消息的时候,由于网络等原因,消息没有收到,这个时候可以开启mq的事务机制,如果没有收到生产者消息就抛出异常,回滚,然后重试发送消息。当然这样太消耗性能。一般不被人们选择。但是生产者可以开启confirm 模式。它与事务机制最大的不同就是confirm是异步的,不会阻塞。大概流程是,每次写消息的时候都会给消息分配一个唯一id,如果写入成功,mq会回一个ack消息。如果mq没处理这条消息,就回调一个nack接口,通知生产者接受失败。同时自己可以维护这条消息,比如超过一定时间没回复就继续发送。

  2. 如果是RabbitMQ丢了消息,可以让消息持久化。持久化也不是及时的更新到硬盘中,可以和confirm结合使用。等到mq持久化到硬盘上以后再给生产者发ack消息。

  3. 消费端丢失数据,不开启自动ack机制,当消费完了再手动ack给mq

如何保证消息的顺序性?

queue天然就是顺序的。但是多个consumer用一个queue也是会有问题。rabbitmq:拆分多个queue,每个queue一个consumer。或者一个queue只对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底部不同worker处理。

如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

  • 幂等性,不怕重复消费。

  1. 利用数据库唯一约束实现幂等

可以通过给消息的某一些属性设置唯一约束,比如增加唯一uuid,添加的时候查询是否存对应的uuid,存在不操作,不存在则添加,那样对于相同的uuid只会存在一条数据。其实,只要类似“insert if not exist”的操作都可能,但需要保证查询跟添加的操作必须是原子性操作。

  1. 设置前置条件

在更新的时候,可以通过设置一定的前置条件来保证数据幂等,比如给用户发送短信是非幂等操作,但可以添加前置条件,变成如果改用户未发送过短信,则给用户发送短信,此时的操作则是幂等性操作。但在实际上,对于一个问题如何获取前置条件往往比较复杂,此时可以通过设置版本号version,没修改一次则版本号+1,在更新时则通过判断两个数据的版本号是否一致。

  1. 通过全局ID实现 最后的方式就比较暴力也比较通用,通过设置全局Id去实现。实现的思路是,在发送消息时,给每条消息指定一个全局唯一的 ID(可以通过雪花算法去实现),消费时,先根据这个 ID 检查这条消息是否有被消费过,如果没有消费过,才更新数据。

消息队列满了以后该怎么处理?

场景:消费慢、磁盘满、超时等

  • 临时紧急扩容

  • 直接把消息丢掉。做任务补救。等用户量少的时候再灌到mq中。

消息发送失败 如何补救

  • 自动重发

  • 人工干预

如果在面试中遇到了如上问题,恰好你也如上回答,纵然拿不到满分,临阵磨枪,不快也光。

进步就是今天比昨天多知道一点。加油程序少年!2021年好运。

以上是关于没用过消息中间件,是如何忽悠面试官的?的主要内容,如果未能解决你的问题,请参考以下文章

互联网面试必杀:如何保证消息中间件全链路数据100%不丢失:第二篇

面试官:如何保障消息100%投递成功消息幂等性?

互联网面试必杀:如何保证消息中间件全链路数据100%不丢失

哥们,消息中间件在你们项目里是如何落地的?

2023春招面试:消息中间件面试题整理

2023春招面试:消息中间件面试题整理