JAVA工程师面试专题-《消息队列》篇

本文详细探讨了消息队列的使用场景、优缺点比较,包括Kafka、RabbitMQ、RocketMQ和ActiveMQ的特性,以及如何根据需求进行选择和实现顺序消费、高可用和可靠性。同时,讨论了处理消息积压的方法和设计消息队列时的关键要素。
摘要由CSDN通过智能技术生成

​​​​​​​

1、为什么使用消息队列?

解耦、异步、削峰

2、消息队列有什么优缺点

优点:解耦、异步、削峰

缺点:系统可用性降低、系统复杂度提高、一致性问题

3、如何进⾏消息队列选型?

  • Kafka:

○ 优点: 吞吐量⾮常⼤,性能⾮常好,集群⾼可⽤。

○ 缺点:会丢数据,功能⽐较单⼀。

○ 使⽤场景:⽇志分析、⼤数据采集

  • RabbitMQ:

○ 优点: 消息可靠性⾼,功能全⾯。

○ 缺点:吞吐量⽐较低,消息积累会严重影响性能。erlang语⾔不好定制。

○ 使⽤场景:⼩规模场景

  • RocketMQ:

○ 优点:⾼吞吐、⾼性能、⾼可⽤,功能⾮常全⾯。

○ 缺点:开源版功能不如云上商业版。官⽅⽂档和周边⽣态还不够成熟。客户端只⽀持java。

○ 使⽤场景:⼏乎是全场景。

4、ActiveMQ、RabbitMQ、RocketMQ、Kafka比较

  1. 单机吞吐量: ActiveMQ、RabbitMQ 万级;RocketMQ、Kafka 10万级

  2. topic数量对吞吐量影响:RocketMQ几百几千topic性能略微下降,Kafka从几十到几百性能急剧下降

  3. 时效性: RabbitMQ 微秒级别;ActiveMQ、RocketMQ、Kafka 毫秒级别

  4. 可用性:ActiveMQ、RabbitMQ主从架构,高可用;RocketMQ、Kafka分布式架构,可用性非常高

  5. 可靠性:ActiveMQ小概率丢数据;Rabbit几乎不丢;RocketMQ、Kafka通过配置可实现0丢失功能支持

  6. 功能完备度:ActiveMQ极其完备;RabbitMQ性能高延迟低;RocketMQ功能丰富且是分布式架构,易扩展;Kafka功能简单,适合特定场景。

5、RocketMQ

(1)RocketMQ组成部分(角色)有哪些?

  1. 生产者(Producer):负责产生消息,生产者向消息服务器发送由业务应用程序系统生成的消息。

  2. 消费者(Consumer):负责消费消息,消费者从消息服务器拉取信息并将其输入用户应用程序。

  3. 消息服务器(Broker):是消息存储中心,主要作用是接收来自 Producer 的消息并存储, Consumer从这里取得消息。

  4. 名称服务器(NameServer):用来保存 Broker 相关 Topic 等元信息并给 Producer ,提供 Consumer查找 Broker 信息。

(2)RocketMQ消费模式有几种?

集群消费

  • 一条消息只会被同Group中的一个Consumer消费

  • 多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据​​​​​​​

广播消费

  • 消息将对一个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer

属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一

(3)RocketMQ如何保证消息的顺序消费?

生产者有序发送

生产者在投放消息的时候自定义投放策略,我们实现一个MessageQueueSelector接口,使用Hash取模法来保证同一个订单在同一个队列中就行了,即通过订单ID%队列数量得到该ID的订单所投放的队列在队列列表中的索引,然后该订单的所有消息都会被投放到这个队列中。

消费者有序消费

RockerMQ的MessageListener回调函数提供了两种消费模式,有序消费模式MessageListenerOrderly和并发消费模式MessageListenerConcurrently。

在消费的时候,还需要保证消费者注册MessageListenerOrderly类型的回调接口实现顺序消费,如果消费者采用Concurrently并行消费,则仍然不能保证消息消费顺序。

(4)RocketMQ如何保证消息不丢失?

Producer端

采取 send() 同步发消息,发送结果是同步感知的。

发送失败后可以重试,设置重试次数。默认3次。

Broker端

修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。

集群部署

Consumer端

完全消费正常后在进行手动ack确认

(5)RocketMQ执行流程?

  1. 启动 Namesrv,Namesrv起 来后监听端口,等待 Broker、Producer、Consumer 连上来,相当于一个路由控制中心。

  2. Broker 启动,跟所有的 Namesrv 保持长连接,定时发送心跳包。

  3. 收发消息前,先创建 Topic 。创建 Topic 时,需要指定该 Topic 要存储在 哪些 Broker上。也可以在发送消息时自动创建Topic。

  4. Producer 发送消息。

  5. Consumer 消费消息。

(6)消费者获取消息有几种模式?

消费者获取消息有两种模式:推送模式和拉取模式。

PushConsumer

推送模式(虽然 RocketMQ 使用的是长轮询)的消费者。消息的能及时被消费。使用非常简单,内部已处理如线程池消费、流控、负载均衡、异常处理等等的各种场景。

PullConsumer

拉取模式的消费者。应用主动控制拉取的时机,怎么拉取,怎么消费等。主动权更高。但要自己处理各种场景

(7)RocketMQ的事务消息是如何实现的

a. ⽣产者订单系统先发送⼀条half消息到Broker,half消息对消费者⽽⾔是不可⻅的

b. 再创建订单,根据创建订单成功与否,向Broker发送commit或rollback

c. 并且⽣产者订单系统还可以提供Broker回调接⼝,当Broker发现⼀段时间half消息没有收到任

何操作命令,则会主动调此接⼝来查询订单是否创建成功

d. ⼀旦half消息commit了,消费者库存系统就会来消费,如果消费成功,则消息销毁,分布式事

务成功结束

e. 如果消费失败,则根据重试策略进⾏重试,最后还失败则进⼊死信队列,等待进⼀步处理

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

Rabbit:镜像集群

在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。

Kafka:基于分布式实现高可用,多个broker,多partion,多replica,leader读写,follower主动从leader处pull数据

7、如何保证消息不被重复消费?

上下游约定唯一标识

  1. 写库根据唯一键排重

  2. 写redis set天然排重

8、如何保证消息的可靠性传输?

消息可靠传输代表了两层意思,既不能多也不能少。

  1. 为了保证消息不多,也就是消息不能重复,也就是⽣产者不能重复⽣产消息,或者消费者不能重复消费消息

  2. ⾸先要确保消息不多发,这个不常出现,也⽐较难控制,因为如果出现了多发,很⼤的原因是⽣产者⾃⼰的原因,如果要避免出现问题,就需要在消费端做控制

  3. 要避免不重复消费,最保险的机制就是消费者实现幂等性,保证就算重复消费,也不会有问题,通过幂等性,也能解决⽣产者重复发送消息的问题

  4. 消息不能少,意思就是消息不能丢失,⽣产者发送的消息,消费者⼀定要能消费到,对于这个问题,就要考虑两个⽅⾯

  5. ⽣产者发送消息时,要确认broker确实收到并持久化了这条消息,⽐如RabbitMQ的confirm机制,Kafka的ack机制都可以保证⽣产者能正确的将消息发送给broker

  6. broker要等待消费者真正确认消费到了消息时才删除掉消息,这⾥通常就是消费端ack机制,消费者接收到⼀条消息后,如果确认没问题了,就可以给broker发送⼀个ack,broker接收到ack后才会删除消息

9、Kafka如何保证消息的顺序性

在Kafka中Partition(分区)是真正保存消息的地方,发送的消息都存放在这里。Partition(分区)又存在于Topic(主题)中,并且一个Topic(主题)可以指定多个Partition(分区)。

在Kafka中,只保证Partition(分区)内有序,不保证Topic所有分区都是有序的。

所以 Kafka 要保证消息的消费顺序,可以有2种方法:

  1. 1个Topic(主题)只创建1个Partition(分区),这样生产者的所有数据都发送到了一个Partition(分区),保证了消息的消费顺序。

  2. 生产者在发送消息的时候指定要发送到哪个Partition(分区)。

10、RocketMQ的实现原理

RocketMQ由NameServer注册中⼼集群、Producer⽣产者集群、Consumer消费者集群和若⼲Broker (RocketMQ进程)组成,它的架构原理是这样的:

Broker在启动的时候去向所有的NameServer注册,并保持⻓连接,每30s发送⼀次⼼跳

Producer在发送消息的时候从NameServer获取Broker服务器地址,根据负载均衡算法选择⼀台服务器来发送消息

Conusmer消费消息的时候同样从NameServer获取Broker地址,然后主动拉取消息来消费

11、kafka的零拷贝原理

  1. mmap机制

  2. sendfile()

12、说一下 Kafka 中 Partition 分区副本的 Leader 选举算法

Kafka 首先会选择一个具有最新数据的副本作为新的 Leader,也就是 ISR 集合中的副本。其中,ISR(In-Sync Replica)是指与 Leader 同步的副本集合,它们的数据同步状态与 Leader 最接近,并且它们与 Leader 副本的网络通信延迟最小。

如果 ISR 集合中没有可用的副本,Kafka 会从所有副本中选择一个具有最新数据的副本作为新的 Leader。在这种情况下选举出来的 Leader,由于和原来老的 Leader 节点的数据存在较大的延迟,会造成数据丢失的情况

所以 Kafka 设计者把这个功能开关的选择交给了开发者,如果愿意接受这种情况,可以通过unclean.leader.election.enable 参数来设置。开启之后虽然会造成数据丢失,但是至少可以保证依然能对外提供服务,保证了可用性

13、大量消息积压,如何处理?

  1. consumer出问题,首先修复consumer问题,恢复其消费速度。

  2. 新建10个queue,程序分发原来队列里面的数据到10个queue里面,10倍consumer机器,每一批消费一个queue,处理完成之后恢复原来架构。

14、如何设计一个消息队列?

可伸缩性,broker -> topic -> partition

可靠性,消息持久化,磁盘顺序写,数据零丢失方案

可用性,多副本 -> leader & follower -> broker 挂了重新选举 leader

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农滴自我修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值