Java 八股文:MQ 篇

3 - MQ 篇

消息中间件用于分布式系统中程序之间的异步通信。它基于消息的发布/订阅或点对点机制,实现高效、可靠、可伸缩的消息传递。

3.1 RabbitMQ

3.1.1 RabbitMQ 如何保证消息不丢失?消息丢失了怎么办?

如何保证消息不丢失?

  1. 开启生产者 确认机制,确保生产者的消息 ack 能到达队列。
  2. 开启 持久化功能,确保消息未消费前在队列中不会丢失
  3. 开启消费者 确认机制 auto,由 spring 确认消息处理成功后完成 ack。
  4. 开启消费者 失败重试机制,多次失败后将消息投递到 异常交换机,交由人工处理。

alt

消息丢失了怎么办?

  1. 生产者发送消息失败:消息未能成功发送到MQ。

    • 消息重发:生产者应实现自动重试机制。

    • 本地存储:在发送失败时,将消息暂存至本地(数据库或文件系统)。

    • 日志记录:记录失败详情,便于问题追踪和分析。

  2. 消息在传输过程中丢失:消息在生产者到MQ或MQ到消费者传输过程中丢失。

    • 消息重发:生产者应实现消息重发机制。
  3. 消息队列内部消息丢失:MQ内部故障,如节点崩溃或磁盘故障。

    • 高可用配置:通过集群配置提高容错能力。

    • 事务日志:如RabbitMQ配置消息日志,Kafka使用事务日志。

    • 备份与恢复:定期备份消息和队列状态,以便硬件故障时恢复。

  4. 消费者处理消息时丢失:消费者在处理消息过程中发生异常。

  • 消息重发:生产者配合实现消息重发。

  • 未确认消息重发:MQ将未确认消息重新放回队列。

  • 死信队列:消息处理失败或超时后转移到死信队列。

3.1.2 RabbitMQ 怎么保证消息的顺序性?怎么避免消息重复消费?
  • 保证消息的顺序性的方法

    • 单一消费者:可以将消息队列的消费者数量设置为1,这样就可以保证消息的顺序性。

    • 分区消费:将消息按照不同的分区进行发送和消费,每个分区只有一个消费者,这样可以保证每个分区的消息顺序性。

    • 消息排序:在消息队列中添加消息排序的功能,根据消息的ID或者其他标识进行排序,保证消息的顺序性。

  • 避免消息重复消费的方法

    • 消息去重:可以记录已经消费过的消息的 ID 或者其他标识,再次消费时先进行判断,如果已经消费过则跳过该消息。

    • 消费者确认机制:消费者在消费完一条消息后,需要向消息队列发送确认消息,告诉消息队列这条消息已经被消费。

      如果消息队列没有收到确认消息,则会将该消息重新发送给其他消费者进行消费。

    • 幂等性处理:在消费消息时,可以使用幂等性处理来保证消息不被重复消费。

      幂等性处理指的是对于同一个操作,多次执行所产生的结果是一致的,不会产生副作用。

alt

3.1.3 RabbitMQ 延迟队列有了解过嘛?
  1. 死信队列
    • 当消息无法被正常消费时(如被拒绝或过期),会被发送到死信队列中。
    • 可以通过设置消息的TTL(Time To Live)来实现延迟效果。
  2. 插件方式
    • 使用 rabbitmq_delayed_message_exchange 插件,可以创建延迟交换机(DelayExchange)
    • 在发送消息时指定 x-delay 头,该头的值即为延迟时间(毫秒)。这种方式不需要额外的死信队列配置。
3.1.4 RabbitMQ 消息堆积如何解决?

消息堆积:通常发生在生产者生产速度远大于消费者消费速度时,以下是几种解决方案:

  1. 增加消费者数量:在消费者机器重启后,增加更多的消费者进行处理。
  2. 多线程处理:在消费者处理逻辑内部开辟线程池,利用多线程的方式提高处理速度。
  3. 扩大队列容量:提高队列的堆积上限,但这并不是根本解决方案。
  4. 惰性队列:它将消息直接存储到磁盘而非内存,支持百万级消息的存储,适用于消息堆积严重的情况。
3.1.5 RabbitMQ 的高可用机制有了解过嘛?
  1. 集群模式:通过多节点集群部署,实现数据的冗余存储和负载均衡。
  2. 镜像队列:将队列的数据复制到多个节点上,即使某个节点宕机,其他节点仍然可以继续提供服务。
  3. Quorum 队列:类似于镜像队列,但提供了更强的一致性保证。
  4. 分区处理策略:在网络分区发生时,RabbitMQ 提供了自动修复、忽略和暂停少数节点等策略,以保证系统的高可用性。
3.1.6 为什么选择 RabbitMQ?有什么好处?

RabbitMQ 的功能比较丰富 , 支持各种消息收发模式(简单队列模式, 工作队列模式 , 路由模式 , 直接模式 , 主题模式等)。

支持延迟队列 , 惰性队列而且天然支持集群, 保证服务的高可用, 同时性能非常不错 , 社区也比较活跃, 文档资料非常丰富。

  1. 消息解耦:使用RabbitMQ作为中间件,可以将各个系统解耦,减少系统间的直接依赖。提升容错性和可维护性。

  2. 异步处理:将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。

    使用RabbitMQ以后,可以将耗时的操作异步化,提高应用程序的响应时间,从而提高用户体验和系统吞吐量。

  3. 削峰填谷:在订单处理等场景中,可能会出现短时间内大量用户下单的情况。

    通过使用RabbitMQ作为缓冲层,可以将这些订单请求分散成一段时间来处理,避免系统在峰值时过载。

  4. 消息持久化:支持消息持久化,可以保证即使在系统重启或者故障的情况下,未完成的任务也不会丢失,可以继续被处理。

  5. 多种通信协议和规则:支持多种消息通信协议和规则,例如AMQP、STOMP和MQTT等,可以满足不同应用程序的需求。

3.1.7 消息中间件的消费模式有几种?
  1. 单一消费者模式:一个消息队列由一个消费者进行消费,消息按照顺序逐个被处理。
  2. 竞争消费者模式:一个消息队列由多个消费者进行消费,消息被多个消费者竞争处理。
  3. 发布订阅模式:消息被发布到一个交换机,然后广播到所有队列,多个消费者从这些队列中消费消息。
  4. 路由模式:消息被发布到一个交换机,然后路由到特定队列,多个消费者从这些队列中消费消息。

3.2 Kafka

3.2.1 Kafka 如何保证消息不丢失?
  1. 消息持久化:确保所有的消息都被写入到磁盘上。
  2. 副本机制:每个分区的数据都保存多个副本,通常至少有三个副本。
  3. 同步提交:生产者在发送消息时,可以设置为同步提交,确保消息被所有副本接收后才认为是成功。
  4. Leader选举:当Leader副本宕机时,会从Follower副本中选举出新的Leader,保证服务的连续性。
3.2.2 Kafka 怎么保证消息的顺序性?怎么避免消息重复消费?
  • 保证消息的顺序性的方法
    • 单线程消费:在同一消费者实例中,对同一个分区的消息进行顺序消费。
    • 分区顺序:确保每个分区内的消息是顺序消费的,但不同分区之间的消息顺序可能不一致。
    • 消费者组:在消费者组内,每个消费者负责不同的分区,可以保证分区内消息的顺序性。
  • 避免消息重复消费的方法
    • 幂等生产者:确保即使消息被重复发送,处理结果也是一致的。
    • 消息去重:在消费者端实现去重逻辑,比如通过业务唯一标识符来识别重复消息。
    • 消费状态存储:将消费状态存储在外部存储系统中,以便在消费者重启后能够从上次消费的位置继续。
3.2.3 Kafka 的高可用机制有了解过嘛?
  1. 集群部署:通过多节点集群部署,实现负载均衡和故障转移。
  2. 数据副本:每个分区的数据都有多个副本,提高数据的可用性。
  3. Leader和Follower:每个分区都有一个Leader和多个Follower,Leader负责数据的读写,Follower负责数据的复制。
3.2.4 解释一下 Kafka 复制机制中的 ISR?

ISR(In-Sync Replicas)是Kafka中用于描述与Leader副本保持同步的Follower副本集合。

  • 当Follower副本落后于Leader副本太多时,会被踢出ISR,此时Leader副本会等待Follower副本赶上来。
  • 如果Leader副本宕机,会从ISR中选举出新的Leader。
3.2.5 为什么选择 Kafka?有什么好处?

Kafka的高性能设计包括:

  1. 批处理:消息以批处理的方式发送和接收,减少网络请求次数。
  2. 零拷贝技术:使用sendfile系统调用,减少数据拷贝的开销。
  3. 分区:通过分区提高并行处理能力,每个分区可以独立进行读写操作。
  4. 磁盘I/O优化:顺序写入磁盘,提高写入效率。
3.2.7 介绍一下 Kafka 数据存储和清理?
  1. 数据存储:消息被存储在磁盘上,支持持久化。
  2. 日志分段:Kafka将数据存储为日志文件,每个日志文件有一个固定的大小,当达到大小时会自动创建新的日志文件。
  3. 日志清理:支持基于时间或日志文件大小的清理策略,如删除旧的日志文件或压缩日志文件。
  4. 日志压缩:对旧的日志文件进行压缩,节省存储空间。
#java##八股文##消息队列#
全部评论

相关推荐

真实工作体验~先说结论:非常安利!!! 在滴滴成长很快,对新人有培养体系。老板们和同事都很职业,能力强,培养了我比较好的职业习惯,也拿到了比较好的结果。当然有时候压力也会大一点点,挺过去就好了。 上下班不打卡,包晚餐,9点后打车免费。有商保报销90%,过节有公司礼盒。有人情味,相较其他厂老人(3年以上司龄)相对更多些!⭐关于职场氛围:真的很爱滴滴🍊的氛围,大家都很亲近,组里人也会一起吃饭,而且经常被请客,嘻嘻。还有就是可能职场不是很大,整个二楼一半人我都认识了!我从最开始比较害羞到慢慢主动和别人搭话噜,感觉这次实习认识的小伙伴还是比较多的! ⭐关于成长:mt和同事不管在日常工作上还是求职、职业规划上都给我提供了帮助,花时间辅导我面试、回答我幼稚的问题…这些都让我很感激!而且我也看到了他们的工作状态,对商分、数分有了一些理解。有时候和他们的交流给迷茫时期的我带来了一些慰藉。不过有时候组里忙起来可能就没人管我,所以我也狠狠摸鱼了 ⭐通勤不太方便是真的,上海职场离地铁站老远了,而且地理位置离上海哪个高校都远;晚上的饭菜也不是很好吃;茶水间只有开水…… 但是工位不挤,实习生独立工位这点还是蛮好嘟;而且楼下有健身房,有时间可以去跑个步哦~ ⭐很爱Mac book前置拍出来糊糊的感觉!宝子们可以试一下hhh,摸鱼不干别的就是自拍、养花、吃零食滴滴2026届秋招储备实习生招聘正式启动啦!🚘岗位类别工程/算法/数据/安全技术/效能管理/产品/商业分析/金融模型/运营/专业职能/其他🚘投递要求2025年9月~2026年8月之间毕业的海内外高校毕业生,每人可投递1个岗位🚘工作地点北京/杭州/上海等🚘招聘流程简历投递(4.15起)-面试安排-Offer发放🚘【内推链接】https://app.mokahr.com/campus-recruitment/didiglobal/96064?recommendCode=DScKP9qC#/jobs【内推码】DScKP9qC立刻投递,快人一步,抢跑未来立刻投递,快人一步,抢跑未来!大家投递完可以在评论区打上姓名缩写+岗位(比如PM+LJJ),我来确认有没有内推成功喽                                                                                                                                                                                                                                                                       
点赞 评论 收藏
分享
1. STAR 方法使用 STAR 方法(Situation, Task, Action, Result)可以有效结构化你的回答,帮助你展示能力和经历。Situation(情境):描述你所处的背景和环境。Task(任务):你需要解决的问题或完成的任务。Action(行动):你采取的具体行动和使用的技能。Result(结果):结果如何,突出成就和影响。示例: “在我负责的一个项目(Situation),我们的客户端对某一功能有很高的需求(Task)。我用 React 重构了这个模块(Action),结果不仅提升了用户体验,加载速度提高了50%(Result)。”2. 量化结果面试中可以通过量化的结果来增强说服力,展示你的成果,便于让面试官更直观地了解你的能力。使用数据:如“我将项目的测试覆盖率提升到85%”或者“通过优化代码,使加载时间减少了40%”。3. 讲故事通过讲故事的方式,让回答更生动有趣,同时也能留给面试官更深刻的印象。引人入胜:开头简要交代故事背景,接着详细描述过程中遇到的挑战和解决方案,最后总结收获和成果。4. 诚实与反思在谈论自己的缺点时,表现出诚实和反思能力,可以让你显得更真实可信。承认缺点:如“我过去在时间管理上有些欠缺,但我现在开始使用项目管理工具,并制定了更合理的时间安排,正在持续改进中。”5. 实践与准备提前准备并模拟面试,可以帮助你提高自信心与应对能力。模拟练习:找朋友进行模拟面试,练习回答常见问题,并获得反馈。收集反馈:对每次模拟面试的表现进行总结,优化回答内容和表达方式。https://www.nowcoder.com/issue/tutorial?zhuanlanId=j572L2&uuid=d3520e4b0ad640008bc5305fd6838a1c
点赞 评论 收藏
分享
评论
8
39
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务