扎心了!面试官:你都工作三年了,怎么连保证消息的顺序性都不会

作为一名java程序员,求职面试时,关于消息中间件的问题时常会遇到,张工是一名java程序员,最近到某知名互联网公司面试,面试官提出这样的一个问题:

如何保证消息的顺序性?

张工一时间没有回答上来,面试官:你都工作三年了,怎么连保证消息的顺序性都不会啊。被面试官这么一说,张工都不好意思了。

其实面试官问这个问题无非就是考察两点:

  • 考察你对消息顺序是否了解?

  • 如何保证消息的有序性?

比如有这样一个需求,需要对MySql数据库的binlog日志进行采集,就是数据从一个 mysql 库同步到另一个 mysql 库。

要是有这样的一个操作:在 mysql 里对一条数据进行增删改操作,对应就有增删改 3 条 binlog 日志,接着这三条 binlog 发送到消息队列里,再通过Kafka或是RabbitMQ消费出来依次执行,这时就要保证消息的有序性了,要不然本来是增加、修改、删除这样的顺序;结果变成删除、修改、增加,顺序错乱了,本来这个数据同步过来最后应该是被删除了,结果顺序搞错了导致最后这个数据保留下来了,这个数据同步就出问题了。

我们来看看顺序错乱的两个场景:

  1. Kafka:比如说我们建了一个 topic,有三个 partition。生产者在写的时候,其实可以指定一个 key,比如说我们可以指定了某个订单 id 作为 key,那么这个订单相关的数据,会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的。消费者从 partition 中取出来数据的时候,也一定是有顺序的。到这一步,顺序并没有问题。但是,接着我们在消费者里可能会搞多个线程来并发处理消息。因为如果消费者是单线程消费处理,而处理比较耗时的话,多个线程并发跑的话,这时顺序就有可能错乱了。

  2. RabbitMQ:一个 queue,多个 consumer。比如:生产者向 RabbitMQ 里发送了三条数据,顺序依次是 A/B/C,压入的是 RabbitMQ 的一个内存队列。有三个消费者分别从 MQ 中消费这三条数据中的一条,结果消费者2先执行完操作,把 B存入数据库,然后是 A/C。这明显出错了。

解决方案

Kafka

N 个内存 queue,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue ,这样就能保证顺序性了。

RabbitMQ

  1. 拆分多个 queue,每个 queue 对于一个 consumer,这样多了一些 queue ,并没有问题,就是比较麻烦;

  2. 或者就一个 queue 对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后交给底层不同的 worker 去处理。

总结:

关于消息队列,平时工作中要注意总结和积累,查漏补缺,不断完善自己的知识体系。

由于笔者水平有限,文中纰漏之处在所难免,权当抛砖引玉,不妥之处,请大家批评指正。

-END-

作者:洪生鹏  白天搬砖,晚上摆地摊。技术交流、媒体合作、品牌宣传请添加微信: hsp-88ios

猜你喜欢

终于知道阿里字节这样的大公司,为什么面试时经常拿final来考验求职者了

别闹,35岁哪里是程序员的危机

一直搞不清楚什么是读写分离,主从复制的原理,今天总算搞懂了

更多惊喜,请长按二维码识别关注

你若喜欢,别忘了点【在看

你可能感兴趣的:(扎心了!面试官:你都工作三年了,怎么连保证消息的顺序性都不会)