为什么使用消息队列?
解耦、异步、削峰
消息队列有什么优点和缺点?
优点:解耦、异步、削峰
缺点:系统的可用性降低、系统的复杂性提高了、一致性问题。
Kafka的特性
1.消息持久化
2.高吞吐量
3.扩展性
4.多客户端支持
5.Kafka Streams
注意:当你不会说的时候,就围绕着kafka你知道的kafka的功能来说,比方说消息的持久化机制。
RabbitMQ上的一个queue中存放的message是否有数量限制?限制是多少
默认情况下一般是无限制,因为限制取决于机器的内存,但是消息过多会导致处理效率的下降。
可以通过参数来限制, x-max-length :对队列中消息的条数进行限制 , x-max-length-bytes :对队列中消息的总量进行限制
说一说Kafka你熟悉的参数?
创建生产者对象时有三个属性必须指定
bootstrap.servers:说白了就是指定都有哪些节点
key.serializer:键的序列化器
value:serializer: 值的序列化器
acks:指定了必须要有多少个分区副本收到消息,生产者才会认为写入消息是成功的,这个参数对消息丢失的可能性有重大影响。
acks=0:⽣产者不等待broker对消息的确认,只要将消息放到缓冲区,就认为消息已经发送完成。
acks=1: 表示消息只需要写到主分区即可,然后就相应客户端,而不等待副本分区的确认。
acks=all: 表示消息需要写到主分区,并且会等待所有的ISR副本分区确认记录。
retries:重试次数,当消息返送出现错误的时候,系统会重发消息。根客户端收到错误时,重发一样。
compression.type:指定消息的压缩类型。
max.request.size:控制生产者发送请求的最大大小。
request.timeout.ms:客户端等待请求响应的最大值。说白了就是一个超时时间。
batch.size:当多个消息被发送同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。当批次内存被填满后,批次里的所有消息会被发送出去。
kafka中,可以不用zookeeper么?
在新版本的kafka中可以不使用zookeeper。但是kafka本身是自带zookeeper的。但是为了安全考虑,我们通常会外接我们自己的zookeeper。现在的新版本可以使用Kafka with Kraft,就可以完全抛弃zookeeper。
为什么Kafka不支持读写分离?
1、数据一致性问题:数据从主节点转到从节点,必然会有一个延时的时间窗口,这个时间窗口会导致主从节点之间的数据不一致。
2、延时问题:Kafka追求高性能,如果走主从复制,延时严重
Kafka中是怎么做到消息顺序性的
一个 topic,一个 partition,一个 consumer,内部单线程消费,最傻瓜式的一种做法。
构建ProducerRecord消息的时候,我们可以通过构造方法指定要发送到哪个分区。
public ProducerRecord(String topic, Integer partition, K key, V value, Iterable<Header> headers) {
}
Kafka为什么那么快?
- 利用 Partition 实现并行处理
- 顺序写磁盘
- 充分利用 Page Cache
- 零拷贝技术
- 批处理
- 数据压缩
如何解决重复消费?
所有的MQ 是无法保证消息不被重复消费的,只能业务系统层面考虑。利用redis进行业务方面的去重。
Rocketmq如何保证高可用性?
1、架构层面
避免用单节点或者简单的一主一从架构,可以采取多主多从的架构,并且主从之间采用同步复制的方式进行数据双写。
2、刷盘策略
RocketMQ默认的异步刷盘,可以改成同步刷盘SYNC_FLUSH。
3、生产消息的高可用
当消息发送失败了,在消息重试的时候,会尽量规避上一次发送的 Broker,选择还没推送过该消息的Broker,以增大消息发送的成功率。
4、消费消息的高可用
消费者获取到消息之后,可以等到整个业务处理完成,再进行CONSUME_SUCCESS状态确认,如果业务处理过程中发生了异常那么就会触发broker的重试机制。
RocketMq的存储机制了解吗(这个下来再好好看看)?
消息生产者发送消息到broker,都是会按照顺序存储在CommitLog文件中,每个commitLog文件的大小为1G。
CommitLog-存储所有的消息元数据,包括Topic、QueueId以及message。文件
CosumerQueue-消费逻辑队列:存储消息在CommitLog的offset。文件
IndexFile-索引文件:存储消息的key和时间戳等信息,使得RocketMq可以采用key和时间区间来查询消息 。
也就是说,rocketMq将消息均存储在CommitLog中,并分别提供了CosumerQueue和IndexFile两个索引,来快速检索消息。
RocketMq性能比较高的原因?
1.顺序写
顺序写比随机写的性能会高很多,不会有大量寻址的过程
2.异步刷盘
相比较于同步刷盘,异步刷盘的性能会高很多
3.零拷贝
使用mmap的方式进行零拷贝,提高了数据传输的效率
有几百万消息持续积压几小时,说说怎么解决?
1.一般情况下,是消费者的问题,赶紧修复消费者。
2.如果你将消费者修复好了之后,但是mq里面积压的消息量比较大,消费完了可能需要很长的世间,在业务上不能接受,这个时候,
我们可以将原来的消费者停掉。然后征用10倍的机器来部署producer,将原来生产者里面积压的消息快速消费掉。
然后将原来的生产者也停掉。
再征用10倍的机器部署consumer,然后再快速消费倒腾过来的积压数据。
等快速消费完积压的数据之后,将征用过来的机器都释放掉,最后再恢复原来的生产者和消费者就可以了。
Rocketmq中Broker的部署方式
1.单Master 部署;
2.多Master部署
3.多Master多Slave部署
Rocketmq中Broker的刷盘策略有哪些?
同步刷盘
异步刷盘
什么是路由注册?RocketMQ如何进行路由注册与发现?
RocketMQ的路由注册是通过broker向NameServer发送心跳包实现的,首先borker每隔30s向nameserver发送心跳语句,nameserver处理。
RocketMQ的路由发现不是实时的,NameServer不会主动向客户端推送,而是客户端定时拉取主题最新的路由,然后更新。
step1:调用RouterInfoManager的方法,从路由表topicQueueTable、brokerAddrTable、filterServerTable分别填充信息;
step2:如果主题对应的消息为顺序消息,则从NameServerKVconfig中获取关于顺序消息相关的配置填充路由信息;
什么是路由剔除?RocketMQ如何进行路由剔除?
路由删除有两个触发节点:
1)NameServer定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差,如果大于120S,就需要删除;
2)Broker在正常关闭使,会执行unregisterBroker命令。
两种方法删除的逻辑都是一致的。
step1:申请写锁
step2:从brokerLiveTable、filterServerTable移除,从brokerAddrTable、clusterAddrTable、topicQueueTable移除
step3:释放锁
使用RocketMQ过程中遇到过什么问题?
1、消息挤压问题
2、消息丢失问题
3、消息重复消费问题
4、RocketMQ内存不够OOM问题
RocketMQ的总体架构,以及每个组件的功能?
讲一讲RocketMQ中的分布式事务及实现
总结:使用的是半消息+事务回查机制来做的。
讲一讲RocketMQ中事务回查机制的实现
TODO: 太难了,先放过。
标签:RocketMQ,面试题,Kafka,发送,消息,消息中间件,路由,刷盘 From: https://www.cnblogs.com/dongyaotou/p/18411878