【六月更文打卡】RocketMQ面试题

117 阅读2分钟

1、RocketMQ Broker中的消息被消费后会立即删除吗?

不会,每条消息都会持久化到CommitLog中,每个Consumer连接到Broker后会维持消费进度信息,当有消息消费后只是当前Consumer的消费进度(`CommitLog的offset)更新了。

追问:那么消息会堆积吗?什么时候清理过期消息?

默认72小时后会删除不再使用的CommitLog文件

检查这个文件最后访问时间
判断是否大于过期时间
指定时间删除,默认凌晨4点

2、RocketMQ消费模式有几种?

消费模型由Consumer决定,消费维度为Topic。

集群消费
一条消息只会被同Group中的一个Consumer消费
多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据
广播消费
消息将对一个Consumer Group下的各个Consumer实例都消费一遍。即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次。

  /**
     * 3. 设置消息模式,默认是CLUSTERING
     * MessageModel.BROADCASTING 广播消费模式
     * MessageModel.CLUSTERING   集群消费模式
     */
    consumer.setMessageModel(MessageModel.BROADCASTING);

3、消费消息是push还是pull?

RocketMQ没有真正意义的push,都是pull,虽然有push类,但实际底层实现采用的是长轮询机制,即拉取方式。

broker端属性 longPollingEnable 标记是否开启长轮询。默认开启

追问:为什么要主动拉取消息而不使用事件监听方式?
事件驱动方式是建立好长连接,由事件(发送数据)的方式来实时推送。

如果broker主动推送消息的话有可能push速度快,消费速度慢的情况,那么就会造成消息在consumer端堆积过多,同时又不能被其他consumer消费的情况。而pull的方式可以根据当前自身情况来pull,不会造成过多的压力而造成瓶颈。所以采取了pull的方式。

// 1. 创建消费者(Pull)对象
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("GROUP_TEST");
// 1. 创建消费者(Push)对象
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("GROUP_TEST");

4、broker如何处理拉取请求的?

Consumer首次请求Broker

Broker中是否有符合条件的消息
有 ->响应Consumer
等待下次Consumer的请求
没有
PullRequestHoldService 来Hold连接,每个5s执行一次检查pullRequestTable有没有消息,有的话立即推送
每隔1ms检查commitLog中是否有新消息,有的话写入到pullRequestTable
当有新消息的时候返回请求
挂起consumer的请求,即不断开连接,也不返回数据使用consumer的offset。