11 、RocketMQ Broker中的消息被消费后会立即删除吗?
不会,每条消息都会持久化到CommitLog中,每个Consumer连接到Broker后会维持消费进度信息,当有消息消费后只是当前Consumer的消费进度(CommitLog的offset)更新了。
追问:那么消息会堆积吗?什么时候清理过期消息?
4.6 版本默认48小时后会删除不再使用的CommitLog文件
检查这个文件最后访问时间;判断是否大于过期时间;指定时间删除,默认凌晨4点
12 、RocketMQ消费模式有几种?
消费模型由consumer决定,消费维度为Topic。
集群消费:一条消息只会被同group中的一个consumer消费;多个group同时消费一个Topic时,每个group都会有一个consumer消费到数据。
广播消费:消息将对一 个consumer Group下的各个consumer实例都消费一遍。即使这些consumer属于同一个consumer Group ,消息也会被Consumer Group中的每个Consumer都消费一次。
RocketMQ没有真正意义的push,都是pull,虽然有push类,但实际底层实现采用的是长轮询机制拉取方式。broker端属性longPollingEnable标记是否开启长轮询。默认开启
追问:为什么要主动拉取消息而不使用事件监听方式?
事件驱动方式是建立好长连接,由事件(发送数据)的方式来实时推送。如果broker主动推送消息的话有可能push速度快,消费速度慢的情况,那么就会造成消息在consumer端堆积过多,同时又不能被其他consumer消费的情况。而pull的方式可以根据当前自身情况来pull,不会造成过多的压力而造成瓶颈。所以采取了pull的方式。
14 、broker如何处理拉取请求的?
consumer首次请求Broker
a、Broker中是否有符合条件的消息
有 -> 响应consumer;等待下次consumer的请求;
没有-> DefaultMessageStore#ReputMessageService#run方法;PullRequestHoldService来Hold连接,每个5s执行一次检查pullRequestTable有没有消息,有的话立即推送;每隔1ms检查commitLog中是否有新消息,有的话写入到pullRequestTable;当有新消息的时候返回请求;挂起consumer的请求,即不断开连接,也不返回数据;使用consumer的offset。
15 、RocketMQ如何做负载均衡?
通过Topic在多Broker中分布式存储实现。
producer端:发送端指定message queue发送消息到相应的broker,来达到写入时的负载均衡
提升写入吞吐量,当多个producer同时向一个broker写入数据的时候,性能会下降
消息分布在多broker中,为负载消费做准备
默认策略是随机选择:
producer维护一个index;每次取节点会自增;index向所有broker个数取余;自带容错策略
其他实现:hash方法,随机,和自定义实现MessageQueueSelector接口中的select方法。
consumer端:采用的是平均分配算法来进行负载均衡。
其他负载均衡算法:平均分配策略(默认);环形分配策略;手动配置分配策略;一致性哈希等。
追问:当消费负载均衡consumer和queue不对等的时候会发生什么?
Consumer和queue会优先平均分配,如果Consumer少于queue的个数,则会存在部分Consumer消费多个queue的情况,如果Consumer等于queue的个数,那就是一个Consumer消费一个queue,如果Consumer个数大于queue的个数,那么会有部分Consumer空余出来,白白的浪费了。
16 、高吞吐量下如何优化生产者和消费者的性能?
开发方面:同一group下,多机部署,并行消费;单个consumer提高消费线程个数;批量消费方面消息批量拉取,业务逻辑批量处理
运维方面:网卡调优;jvm调优;多线程与cpu调优;Page Cache
17 、再说说RocketMQ 是如何保证数据的高容错性的?
在不开启容错的情况下,轮询队列进行发送,如果失败了,重试的时候过滤失败的Broker;
如果开启了容错策略,会通过RocketMQ的预测机制来预测一个Broker是否可用;
如果上次失败的Broker可用那么还是会选择该Broker的队列;
如果上述情况失败,则随机选择一个进行发送;
在发送消息的时候会记录一下调用的时间与是否报错,根据该时间去预测broker的可用时间。
18 、任何一台Broker突然宕机了怎么办?
Broker主从架构以及多副本策略。Master收到消息后会同步给Slave,这样一条消息就不止一份了,Master宕机了还有slave中的消息可用,保证了MQ的可靠性和高可用性。而且Rocket MQ4.5.0开始就支持了Dlegder模式,基于raft的,做到了真正意义的HA。
19 、Broker把自己的信息注册到哪个NameServer上?
Broker会向所有的NameServer上注册自己的信息。