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。