为什么使用消息队列?
解耦、异步、削峰
消息队列有什么优点和缺点?
优点:解耦、异步、削峰
缺点:系统的可用性降低、系统的复杂性提高了、一致性问题。
RabbitMQ上的一个queue中存放的message是否有数量限制?限制是多少
默认情况下一般是无限制,因为限制取决于机器的内存,但是消息过多会导致处理效率的下降。
可以通过参数来限制, x-max-length :对队列中消息的条数进行限制 , x-max-length-bytes :对队列中消息的总量进行限制
如何解决重复消费?
所有的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集群是怎么搭建的
就说是三主三从的架构。
面试官可能会问你为什么从从节点消费数据呀,因为主节点不是每次来一条数据就同步给从节点,而是够了一个批次之后,一起提交给从节点,这种效率比较高效。
nameserver节点之间是不会相互进行通信的,每个nameserver都维护了全量的borker信息。
如果borker-a主节点挂了之后,borker-slave-a节点是不会被提升为主节点的,它一辈子就是从节点。如果主从同步的方式你指定的是同步复制,那么基本省不会丢失数据,但是如果你指定的是异步复制的方式,那么会丢数据的。
rocketmq中有重试机制,他会看borker-a发送不成功了,会将消息发送到borker-b中。
nameserver1对应的ip是192.168.31.103
nameserver2对应的ip是192.168.31.104
rocketmq的架构是怎么样的,组件有哪些?
RocketMQ 和 kafka 之间有什么区别
适用场景:
rocketmq适合做业务的处理。
kafka适合做日志的处理。
性能:
rocketmq:tps 10w
kafka:tps 100w
结论:kafka性能更高
可靠性:
rocketmq:支持同步刷盘、异步刷盘、同步复制,异步复制
kafka:支持异步刷盘,异步复制
结论:rocketmq的可靠性较好
顺序性:
RocketMQ:支持严格的顺序消息,在顺序消费的场景下,一台broker宕机后,发送消息失败,但不会轮序·
Kakfa:kafka在某些配置下,支持顺序消息,但在一台broker宕机后,消息会乱序
结论:RocketMQ的顺序性较好
消费失败重试
rocketmq:支持失败重试,支持重试间隔时间顺延。
kafka:不支持
结论:rocketmq胜出
延时消息/定时消息
rocketmq:支持
kafka:不支持
结论:rocketmq胜出
分布式事务:
rocketmq:支持
kafka:不支持
结论:rocketmq胜出
消息回溯
RocketMQ:支持某个时间戳(毫秒级)来回溯消息
Kakfa:支持某个偏移量offset来回溯消息
结论:各有千秋,不分伯仲
消息查询机制
RocketMQ:支持messageid和消息内容查询消息
Kakfa:不支持
结论:RocketMQ胜出
rocketmq几个核心知识点(面试有被问到)
rocketmq发送消息支持同步发送和异步发送。
rocketmq中是不会自动进行主从切换的。说白了就是你只要是从节点,你这辈子也就是从节点,不可能提升为主节点。
rocketmq消息发送失败处理:
最多重试两次,这是rocketmq内部实现的
rocketmqmq主节点和从节点的数据同步方式可以采用同步复制或者是异步复制。
rocketmq是通过注册消息监听器的方式来消费消息的,消息监听器大概有这么几种
从这张图中我们能够看到有支持并发消费消息的监听器,有顺序消费消息的监听器。
rocketmq的顺序消息(面试有被问到)
顺序消息指生产者局部有序发送到一个queue,但多个queue之间四全局无序的。
生产者在发送消息的时候我们可以指定MessageQueueSelector的接口,然后在这个接口里面实现我们自定义的将消息发送到哪个messagequeue里面。
public SendResult send(Message msg, MessageQueueSelector selector, Object arg)
throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
msg.setTopic(withNamespace(msg.getTopic()));
return this.defaultMQProducerImpl.send(msg, selector, arg);
}
然后我们在消费消息的时候,一般使用的是注册一个监听器的方式进行消息的消费,这个时候我们使用MessageListenerOrderly这个顺序消费消息的监听器。
rocketmq怎样保证消息不丢失(面试有被问到)
消息发送到生产者是采用同步发送还是再用异步发送,如果采用的是同步发送的方式,这个时候会给我们返回一个结果,我们需要判断这个结果是否成功,如果失败就重新发送。如果采用的是异步发送,这个时候会在callback接口中提供两个方法,一个是onSuccess方法,会传给我们处理结果,这个时候我们可以根据这个结果进行判断,是否需要重新发送。还有一个方法是onException方法,也可以在这个方法里面进行消息的重新发送。说白了就是不管是同步发送还是异步发送,我们都可以根据返回的结果做相应的补偿机制。
mq采用同步刷盘还是异步刷盘,异步刷盘是消息写到缓存中就立刻返回了,为了保证消息不丢失,这个时候我们可以使用同步刷盘的方式。
rocketmq如果是集群模式部署的话,这个时候主从复制我们可以采用同步复制,不要采用异步复制。
消费者在拿到消息之后,处理完成消息,会自动提交ack应答,比方说我们在处理消息的时候出现了异常,这个时候还想重复消费这条消息,我们就需要关闭自动应答,改为手动应答的方式。
还有就是消息在发送之前,可能因为网络抖动的原因,压根就没有到达mq,这个时候我们可以在消息发送之前设置一张消息日志表,将消息先存到这张表里面(采用顺序写的这种方式),然后再进行发送。
标签:RocketMQ,异步,面试题,发送,消息,消息中间件,rocketmq,刷盘 From: https://www.cnblogs.com/dongyaotou/p/18580133