1 Star 0 Fork 31

阿明 / Ebooks

forked from Java精选 / Ebooks 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
2021年消息队列面试题大汇总附答案.md 8.85 KB
一键复制 编辑 原始数据 按行查看 历史

2021年消息队列面试题大汇总附答案

全部面试题答案,更新日期:01月30日,直接下载吧!

下载链接:高清500+份面试题资料及电子书,累计 10000+ 页大厂面试题 PDF

消息队列

题1:AMQP 模型有哪几大组件?

交换器(Exchange)

消息代理服务器中用于把消息路由到队列的组件。

队列(Queue)

用来存储消息的数据结构,位于硬盘或内存中。

绑定(Binding)

一套规则,告知交换器消息应该将消息投递给哪个队列。

题2:如何避免消息重复投递或重复消费?

在消息生产时,MQ内部针对每条生产者发送的消息生成一个inner-msg-id值,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列。

在消息消费时,要求消息体中必须要有一个bizId(对于同一业务全局唯一,比如支付ID、订单ID、帖子ID等)作为去重和幂等的依据,避免同一条消息被重复消费。

针对此类问题,列举处理消息的业务场景:

1、用户获取到消息执行数据库insert插入操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

2、用户获取到消息执行redis缓存set插入操作,不需要解决重复,因为无论set几次结果都是一样的,set操作本来幂等操作。

3、如果上面两种情况还不行,可以考虑使用记录消费。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以Key-Value的形式写入到redis中。当消费者开始消费消息时,首选获取redis中有没消费过该记录。

题3:Zookeeper 对于 Kafka 的作用是什么?

Zookeeper是一个开放源码的、高性能的协调服务,它用于Kafka的分布式应用。

Zookeeper主要用于在集群中不同节点之间进行通信。

在Kafka中,它被用于提交偏移量,因此如果节点在任何情况下都失败了,它都可以从之前提交的偏移量中获取。

除此之外,它还执行其他活动,如:leader检测、分布式同步、配置管理、识别新节点何时离开或连接、集群、节点实时状态等等。

题4:Kafka 中如何减少 ISR 扰动?broker何时离开 ISR?

ISR是一组与leaders完全同步的消息副本,也就是说ISR中包含了所有提交的消息。

ISR应该总是包含所有的副本,直到出现真正的故障。

如果一个副本从leader中脱离出来,将会从ISR中删除。

题5:RabbitMQ 中 broker 和 cluster 分别是指什么?

broker是指一个或多个erlang node的逻辑分组,且node上运行着RabbitMQ应用程序。

cluster是在broker的基础之上,增加了node之间共享元数据的约束。

题6:RabbitMQ 交换器类型有哪些?

RabbitMQ 消费类型也就是交换器(Exchange)类型有以下四种:

direct:轮询方式。

headers:轮询方式,允许使用header而非路由键匹配消息,性能差,几乎不用。

fanout:广播方式,发送给所有订阅者。

topic:匹配模式,允许使用正则表达式匹配消息。

RabbitMQ默认的是direct方式。

题7:RabbitMQ 有几种广播类型?

direct(默认方式):最基础最简单的模式,发送方把消息发送给订阅方,如果有多个订阅者,默认采取轮询的方式进行消息发送。

headers:与direct类似,只是性能很差,此类型几乎用不到。

fanout:分发模式,把消费分发给所有订阅者。

topic:匹配订阅模式,使用正则匹配到消息队列,能匹配到的都能接收到。

题8:Kafka 能否保证永久不丢失数据吗?

Kafka只对“已提交”的消息(committed message)做有限度的持久化保证。所以说,Kafka不能够完全保证数据不丢失,需要做出一些权衡策略。

什么是已提交的消息?

当Kafka的若干个Broker成功地接收到一条消息并写入到日志文件后,它们会告诉生产者程序这条消息已成功提交。此时,这条消息在Kafka看来就正式变为已提交消息了。所以说无论是ack=all,还是ack=1,不论哪种情况,Kafka只对已提交的消息做持久化保证这件事情是不变的。

有限度的持久化保证消息不丢失,也就是说Kafka不可能保证在任何情况下都做到不丢失消息。必须保证Kafka的Broker是可用的,换句话说,假如消息保存在N个Kafka Broker上,那么这个前提条件就是这N个Broker中至少有 1个存活。只要这个条件成立,Kafka就能保证你的这条消息永远不会丢失。

总结的说就是Kafka是能做到不丢失消息的,只不过这些消息必须是已提交的消息,而且还要满足一定的条件。

题9:Kafka 消费者如何不自动提交偏移量,由应用提交?

将auto.commit.offset设为false,然后在处理一批消息后commitSync()或者异步提交commitAsync()即:

ConsumerRecords<> records = consumer.poll(); 
for(ConsumerRecord<> record : records){
   try{
       consumer.commitSync();
   }
}

题10:Kafka 中如何保证消息的有序性?

Kafka的主题是分区有序的,如果一个主题有多个分区,那么Kafka会按照key将其发送到对应的分区中,所以,对于给定的key与其对应的record在分区内是有序的。

Kafka可以保证同一个分区里的消息是有序的,即生产者按照一定的顺序发送消息,Broker就会按照这个顺序将他们写入对应的分区中,同理,消费者也会按照这个顺序来消费他们。

在一些场景下,消息的顺序是非常重要的。比如,先存钱再取钱与先取钱再存钱是截然不同的两种结果。

上面的问题中提到一个参数max.in.flight.requests.per.connections=1,该参数的作用是在重试次数大于等于1时,保证数据写入的顺序。如果该参数不为1,那么当第一个批次写入失败时,第二个批次写入成功,Broker会重试写入第一个批次,如果此时第一个批次重试写入成功,那么这两个批次消息的顺序就反过来了。

一般来说,如果对消息的顺序有要求,那么在为了保障数据不丢失,需要先设置发送重试次数retries>0,同时需要把max.in.flight.requests.per.connections参数设为1,这样在生产者尝试发送第一批消息时,就不会有其他的消息发送给broker,虽然会影响吞吐量,但是可以保证消息的顺序。

除此之外,还可以使用单分区的Topic,但是会严重影响吞吐量。

题11:rabbitmq-中消息是基于什么传输

题12:amqp是什么

题13:kafka-中如何控制消费的位置

题14:什么是消息队列

题15:kafka-与传统-mq-消息队列之间有三个关键区别

题16:监控-kafka-的框架都有哪些

题17:kafka分布式的情况下如何保证消息的顺序消费

题18:kafka-消费者故障出现活锁问题如何解决

题19:amqp-协议层都有哪些

题20:rabbitmq-如何确保每个消息能被消费

题21:rabbitmq-和-kafka-有什么区别

题22:vhost-是什么有什么作用

题23:kafka-中如何查看消费者组是否存在滞后消费

题24:为什么需要消息系统mysql-不能满足需求吗

题25:kafka-中位移-offset-有什么作用

大厂面试题

大厂面试题

大厂面试题

Java
1
https://gitee.com/AminDev/ebooks.git
git@gitee.com:AminDev/ebooks.git
AminDev
ebooks
Ebooks
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891