2019独角兽企业重金招聘Python工程师标准>>>
Broker的BrokerController的初始化中比较核心的就是MessageStore的初始化操作,这章我们根据源码的加载顺序详细的解析MessageStore的初始化及加载操作,涉及到Broker的高性能技术及设计,找到怎么高效的进行内容持久化磁盘操作
一,从BrokerController的构造开始说起
this.messageStore = new DefaultMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener, this.brokerConfig);
1,需要消息存储的配置信息,可以定位存储位置,文件大小,缓存大小等核心配置信息
2,当前brokerStatsManage的管理组件,将操作状态返回给统一的状态统计服务
3,消息抵达的监听服务,主要是将收到的新消息推送给订阅服务的客户端
4,broker的主配置,可以共享主配置内容
二,递进查看DefaultMessageStore的构造解析
public DefaultMessageStore(final MessageStoreConfig messageStoreConfig, final BrokerStatsManager brokerStatsManager, final MessageArrivingListener messageArrivingListener, final BrokerConfig brokerConfig) throws IOException { this.messageArrivingListener = messageArrivingListener; this.brokerConfig = brokerConfig; this.messageStoreConfig = messageStoreConfig; this.brokerStatsManager = brokerStatsManager; //请求定位服务 this.allocateMappedFileService = new AllocateMappedFileService(this); //内容的存储服务 if (messageStoreConfig.isEnableDLegerCommitLog()) { this.commitLog = new DLedgerCommitLog(this); } else { this.commitLog = new CommitLog(this); } //消费者信息定位 this.consumeQueueTable = new ConcurrentHashMap<>(32); //刷新 this.flushConsumeQueueService = new FlushConsumeQueueService(); //清除消息的操作,定期清理过期数据,提前创建文件 this.cleanCommitLogService = new CleanCommitLogService(); //清除消费 this.cleanConsumeQueueService = new CleanConsumeQueueService(); //存储状态 this.storeStatsService = new StoreStatsService(); //索引 this.indexService = new IndexService(this); //高可用的服务配置 if (!messageStoreConfig.isEnableDLegerCommitLog()) { this.haService = new HAService(this); } else { this.haService = null; } //重放,后面跟踪分析 this.reputMessageService = new ReputMessageService(); //调度 this.scheduleMessageService = new ScheduleMessageService(this); //持久存储池化,内存 this.transientStorePool = new TransientStorePool(messageStoreConfig); if (messageStoreConfig.isTransientStorePoolEnable()) { //主要提升性能的池化初始化 this.transientStorePool.init(); } // this.allocateMappedFileService.start(); this.indexService.start(); this.dispatcherList = new LinkedList<>(); this.dispatcherList.addLast(new CommitLogDispatcherBuildConsumeQueue()); this.dispatcherList.addLast(new CommitLogDispatcherBuildIndex()); File file = new File(StorePathConfigHelper.getLockFile(messageStoreConfig.getStorePathRootDir())); MappedFile.ensureDirOK(file.getParent()); lockFile = new RandomAccessFile(file, "rw"); }
1,将必要的构造参数赋值给当前对象
2,构造AllocateMappedFileService服务,该服务是处理Aloocate的请求的异步线程,根据请求生成MappedFile
3,根据配置构造消息的实际物理存储commitLog,该对象是实际的物理文件存储设计
4,构造topic,queue,mappedFile的对应集合
5,构造flush服务,根据消息的内容大小刷新到磁盘中去,确保pagecache的刷盘操作
6,构造清理服务,主要是根据配置时间清理过期的时间,以及处理被hang住的文件
7,构造清楚消费端服务,主要是处理过期的文件,清除过期文件同时清楚对应的索引服务
8,构造存储状态服务,主要是记录操作当前broker的状态
9,构造索引服务,提高快速查询的操作及索引的操作
10,根据配置,构造高可用的服务,主要是主从配置
11,构造重设的服务,该功能是异步线程机制,主要是接受到数据的重构索引等操作
12,构造调度服务,内部基于java的timer实现,实现对配置内容的持久化
13,内存池化构造,TransientStorePool是对nio中ByteBuffer的池化封装,提前构造好对应的数据块
14,将定位mappedFile服务,索引服务进行启动状态
15,构造请求的跳转集合,该集合中有构造消费队列,构造索引
16,初始化文件,该文件的核心属性是文件
三,加载load操作
public boolean load() { boolean result = true; try { //判断标准文件体系是否存在 boolean lastExitOK = !this.isTempFileExist(); log.info("last shutdown {}", lastExitOK ? "normally" : "abnormally"); //加载任务调度 if (null != scheduleMessageService) { result = result && this.scheduleMessageService.load(); } // load Commit Log result = result && this.commitLog.load(); // load Consume Queue result = result && this.loadConsumeQueue(); //成功后加载检查点、索引服务 if (result) { this.storeCheckpoint = new StoreCheckpoint(StorePathConfigHelper.getStoreCheckpoint(this.messageStoreConfig.getStorePathRootDir())); this.indexService.load(lastExitOK); this.recover(lastExitOK); log.info("load over, and the max phy offset = {}", this.getMaxPhyOffset()); } } catch (Exception e) { log.error("load exception", e); result = false; } //成功的标识验证 if (!result) { this.allocateMappedFileService.shutdown(); } return result; }