消息队列精进之路

消息队列相关问题一网打尽
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

硬核考题:如何自己实现一个消息队列

发布于 2024-03-14 | 更新于 2024-06-25

这个问题是一个比较综合的问题,可以考察比较多方面的技能,比如:

  • 考察对消息系统的理解;
  • 考察系统设计能力;
  • 考察你对高可用、高性能、可扩展性等关键技术指标的处理能力。

现在面试都比较喜欢问这类问题。其实你只要对一些开源消息中间件如RocketMQ,Kafka的整体架构和设计思路有所了解,都会有解答思路。

在设计一个消息队列时,你需要考虑以下几个方面:

  • 先讲清楚消息队列整体流程:生产者投递消息给Broker,Broker接收并且存储消息,然后消费者从Broker中获取消息进行消费,有两种消费模式:推模式和拉模式,可以说说优缺点,消息消费完成之后进行消费ACK确认;

  • 生产者如何发现Broker:一般生产者和Broker都是有多台机器的,不可能生产者写死Broker的IP去投递消息,为此,可以引入注册中心,作用类似于RocketMQ的NameServer,存储系统消息队列配置信息,集群实例信息。生产者启动后,把信息注册到注册中心中,并且从注册中心获取到Broker服务器,Topic等信息

  • 注册中心存储的东西:注册中心主要保存以下内容:

    • 存储Topic配置信息:创建Topic的时候,指定Topic要存储在哪些Broker上,并且配置每个Topic要初始化多少个消息队列;
    • Broder的信息,以及Broker和Topic的映射关系:Broker启动之后,就于注册中心保持长连接,定时发送心跳,把自己的信息(IP+端口号)以及存储的所有Topic信息注册到注册中心中;
    • 消费者的信息:启动消费者,消费者把信息注册到注册中心,并且从NameServer获取Broker服务器,Topic的Queue等信息;
    • 生产者的消息:启动生产者,生产者把信息注册到注册中心;
  • 消费者如何发现Broker:消费者在启动的从注册中心获取到所有的Broker服务器,Topic配置信息;

  • 生产者如何投递消息:一个生产者一般对应生产一个Topic的消息,可以从配置中心获取到某个Topic的某台Broker的地址信息,然后与之建立长连接,从而进行消息投递;

  • Broker消息如何持久化:消息可以存储在数据库或者文件系统中,考虑到消息消费的特点,不需要很复杂的查询,并且一般都是顺序写,顺序读的,用文件系统就够了,没必要引入数据库增加架构复杂度。对于需要根据消息id去查找定位消息的场景,可以专门设计一个索引文件;你回答到这里,面试官可能会问,既然用文件系统,如何保证IO读写的效率,这个时候就会继续探讨IO相关知识了,零拷贝那些;

  • 消息的消费关系如何保存:消息消费进度可以存储在一个单独的文件中,记录某个消息消费的偏移量,通过消费者ACK进行推进;

  • 如何实现事务消息:可以结合RocketMQ的事务消息来说说,参考:消息队列#RocketMQ#特性#数据完整性与事务消息

  • 消息队列的弹性设计

    • 对Broker扩容:增加Broker节点数量,从而突破单台Broker的性能瓶颈,可以存储更多的Topic;
    • 对Topic扩容:增加Topic下消息队列的数量,从而支持更多的消费者同时消费消息,提高消息消费吞吐量,并且提高投递消息的处理性能;
    • 由于生产者和消费者的消息都是通过注册中心维护的,这样可以很方便的对部署机器进行增减;
      • 某个生产者节点宕机了,消费者发生Rebalance,是否会发生重复消费
  • 如何保证消息的高可用:回答到这里,一般面试官会继续问如果消息队列某个Broker发生故障了如何保证高可用:

    • Broker故障转移设计:Broker可以做主从部署设计,主节点把消息同步或者异步的发送到从节点,如果要保证同步数据的完整性,就只能使用同步发送的方式了,比如同步到超过多少台机器之后,再响应消息写入成功,这种方式就要消耗性能了;
    • 故障转移:Broker故障转移过程中,消息可能重复消费吗?
    • 重新选主:Broker发生故障转移之后,重新选主是如何实现的?

总之,在回答的时候,可以不断深入探讨,甚至可以举一反三,延伸出第三方中间件中相关问题是如何实现的,需要不断总结和思考。经过不断的思考总结,这些东西将在你的脑海中不再是固化的一个个知识点,而是越来越灵活的工具百宝箱,用到的时候你就会拿出来。

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/faqs/mq/how-to-implement-a-message-queue.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。