先写一半开个头,后面补吧。
消息存储是有ConsumerQueue和CommitLog配合完成。一个Topic里面有多个MessageQueue,每个MessageQueue对于一个ConsumerQueue.ConsumerQueue是一个逻辑队列里面记录者消息的物理存储地址,consumer根据消息的consumeQueue找到消息存储具体路径,从而读取里面信息CommitLog存储文件的字节信息。
首先来看一下RocketMQ的存储服务是怎么启动。
1.broker启动,文件位置org.apache.rocketmq.broker.BrokerStartup(broker包)
public static void main(String[] args) {
start(createBrokerController(args));
}
2.createBrokerController进行broker配置,netty配置;
3.BrokerController.initialize():initialize方法会创建一个DefaultMessageStore,这是Broker的核心存储,然后调用DefaultMessageStore的load方法加载CommitLog和ConsumeQueue对应的文件.
public boolean initialize() throws CloneNotSupportedException {
………………
if (result) {
try {
this.messageStore =
new DefaultMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener,
this.brokerConfig);
this.brokerStats = new BrokerStats((DefaultMessageStore) this.messageStore);
//load plugin
MessageStorePluginContext context = new MessageStorePluginContext(messageStoreConfig, brokerStatsManager, messageArrivingListener, brokerConfig);
this.messageStore = MessageStoreFactory.build(context, this.messageStore);
this.messageStore.getDispatcherList().addFirst(new CommitLogDispatcherCalcBitMap(this.brokerConfig, this.consumerFilterManager));
} catch (IOException e) {
result = false;
log.error("Failed to initialize", e);
}
}
result = result && this.messageStore.load();
………………
}
4.BrokerController.start();调用DefaultMessageStore.start启动消息存储服务。
public static BrokerController start(BrokerController controller) {
try {
controller.start();
String tip = "The broker[" + controller.getBrokerConfig().getBrokerName() + ", "
+ controller.getBrokerAddr() + "] boot success. serializeType=" + RemotingCommand.getSerializeTypeConfigInThisServer();
if (null != controller.getBrokerConfig().getNamesrvAddr()) {
tip += " and name server is " + controller.getBrokerConfig().getNamesrvAddr();
}
log.info(tip);
return controller;
} catch (Throwable e) {
e.printStackTrace();
System.exit(-1);
}
return null;
}
5.createBrokerController.start()启动存储线程。
public void start() throws Exception {
if (this.messageStore != null) {
this.messageStore.start();
}
………………
}
截止到这里,顺着源码一点点的梳理基本上可以看到RocketMQ消息存储流程是怎么启动的了。接下来我们可以看看RocketMQ消息的存储原理。