Java 八股文:MQ 篇

3 - MQ 篇

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

3.1 RabbitMQ

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

如何保证消息不丢失?

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

消息丢失了怎么办?

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

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

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

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

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

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

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

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

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

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

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

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

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

3.1.2 RabbitMQ 怎么保证消息的顺序性?怎么避免消息重复消费?
  • 保证消息的顺序性的方法
    • 单一消费者:可以将消息队列的消费者数量设置为1,这样就可以保证消息的顺序性。

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

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

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

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

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

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

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

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

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. 日志压缩:对旧的日志文件进行压缩,节省存储空间。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容