文章基于rocket-mq4.0 代码分析
server接收到消息后,会将消息分发到对应的ConsumeQueue中,等待client端拉取消费。
核心类:
org.apache.rocketmq.store.DefaultMessageStore.ReputMessageService
类图:
该类继承 ServiceThread -Runnable,是一个线程类;在run方法里会每间隔1ms执行方法:
org.apache.rocketmq.store.DefaultMessageStore.ReputMessageService#doReput
首先会将 reputFromOffset 和 DefaultMessageStore已经确认的offset作比较
if (DefaultMessageStore.this.getMessageStoreConfig().isDuplicationEnable() //
&& this.reputFromOffset >= DefaultMessageStore.this.getConfirmOffset()) {
break;
}
如果当前值已经超过DefaultMessageStore已经确认的值,则不会往下走了
然后通过当前的 reputFromOffset 去 commitLog 里去获取数据,如果获取到了则继续往下走
SelectMappedBufferResult result = DefaultMessageStore.this.commitLog.getData(reputFromOffset);
拿到数据最终调用 doDispatch 方法 处理 ConsumeQueue 和 index 的重建
public void doDispatch(DispatchRequest req) {
final int tranType = MessageSysFlag.getTransactionValue(req.getSysFlag());
switch (tranType) {
//已经确认的的事务消息和普通消息都会放到 Consumequeue里
case MessageSysFlag.TRANSACTION_NOT_TYPE:
case MessageSysFlag.TRANSACTION_COMMIT_TYPE:
DefaultMessageStore.this.putMessagePositionInfo(req.getTopic(), req.getQueueId(), req.getCommitLogOffset(), req.getMsgSize(),
req.getTagsCode(), req.getStoreTimestamp(), req.getConsumeQueueOffset());
break;
case MessageSysFlag.TRANSACTION_PREPARED_TYPE:
case MessageSysFlag.TRANSACTION_ROLLBACK_TYPE:
break;
}
//index的重建
if (DefaultMessageStore.this.getMessageStoreConfig().isMessageIndexEnable()) {
DefaultMessageStore.this.indexService.buildIndex(req);
}
}
往ConsumeQueue(指定的queueId)里放消息,等待消费端的拉取
public void putMessagePositionInfo(String topic, int queueId, long offset, int size, long tagsCode, long storeTimestamp,
long logicOffset) {
ConsumeQueue cq = this.findConsumeQueue(topic, queueId);
cq.putMessagePositionInfoWrapper(offset, size, tagsCode, storeTimestamp, logicOffset);
}