源码阅读-Neo4j-启动

Posted by keys961 on April 17, 2019

1. DB启动

代码调用顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
ServerBootstrapper.start();
    ...
    server = communityBootstrapper.createNeoServer(); // 创建服务端CommunityNeoServer
        factory = communityBootstrapper.createGraphFactory(); // 创建GraphFactory,它会生成图数据库的Facade,数据库的操作都通过这个Facade(即GraphDatabaseFacade)进行
        ...
        new CommunityNeoServer(...); // 最终在这里创建服务端
            db = new LifeCycleManagingDataBase(...); // 在父类创建
            life.add(db); // 添加到LifeCycle中(实为LifeSupport,拥有LifeCycle实例列表)
        ...
    server.start(); // 启动Server
        ...
        life.start(); //在AbstractNeoServer中,遍历启动LifeCycle/LifeSupport
            ... // 接下文

之后再LifeSupport中的启动顺序为:

1
2
3
4
5
6
7
8
init(); // 首先将状态变为STOPPED
...
status = changedStatus(..., LifecycleStatus.STARTING);// 然后将状态变为STARTING
for (instance : instanceList) {
    instance.start(); // 将LifeSupport中的LifeCycle实例启动,详细的见下文
}
...
status = changedStatus(..., LifecycleStatus.STARTED);// 全部正常启动,将状态变为STARTED

而实例中,最重要的是 LifeCycleManagingDataBase的启动,步骤如下:

1
2
3
4
5
6
7
...
this.graph = dbFactory.newGraphDataBase(); // 根据之前创建的Factory,创建了GraphDatabaseFacade,任何操作可通过db.getGraph()获取Facade,从而进行操作
    ...
    facadeFactory = new GraphDataBaseFacadeFactory();// 在CommunityGraphFactory中创建Facade工厂
    facadeFactory.newFacade(); // 真正创建Facade入口
        ...
        initFacade(); // 对Facade初始化,下文接上

life中还有另外2个组件:ServerDependenciesLifeCycleAdapterServerComponentsLifecycleAdapter。它们会创建和启动一个Jetty服务器,用于提供各种REST服务(而前面的核心组件可提供Bolt协议的服务)。

2. GraphDatabaseFacade创建

所以可见,真正的重点在于initFacade()上,因为之后所有的操作都会经过这个Facade。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
platform = createPlatform(); // 创建一个Platform
    new PlatformModule(); // 这里真正创建,里面包含内核的相关内容,如存储布局、文件系统、事务调度、并发管理(锁)、日志、数据恢复、监控、调试诊断信息、页缓存、外部插件(如内核插件、引擎插件、全局插件等)、连接管理等,都以模块形式加入,后文再说,TODO
        ...
edition = editionFactory.apply(platform); // 创建版本模块,做的事情和上面类似,TODO    
... // 省区一些创建,如procedures(Procedure的协调服务), msgLogger(消息日志)
DatabaseManager manager = edition.createDatabaseManager(); // 创建Manager,把之前创建的edition, platform, procedures, msgLogger等塞进去
... // 省去一大堆的创建,很多platform.life.add()添加新模块
edition.createDatabases(manager, config); // 这里开始,真正开始创建DataBase
    manager.createDatabase(name); // 实际上调用Manager的创建
        DataSourceModule dataSource = new DataSourceModule(); 
            ... // 创建DataSource,作为数据源标识,然后将将其添加到platform.life中
        ClassicCoreSPI spi = new ClassicCoreSPI(); // 创建SPI(Service Provider Interface)
        graphDatabaseFacade.init(); // 将Facade初始化完成
        ...
databaseFacade = databaseManager.getDatabaseFacade(); // 此时,Facade初始化完成了,它就是我们要返回的GraphDatabaseFacade
platform.life.start() // 和之前类似,遍历并启动各个LifeCycle模块,各个模块以后会讲,TODO

platform包含的life列表如下:

platform.life

3. LifecycleLifeSupport

上文中,Lifecycle贯穿始终,下面是它的接口:

1
2
3
4
5
6
public interface Lifecycle {
    void init() throws Throwable;
    void start() throws Throwable;
    void stop() throws Throwable;
    void shutdown() throws Throwable;
}

LifeSupport实现了该接口,并且拥有2个关键成员:

  • List<LifecycleInstance> instances
  • List<LifecycleListener> listeners = new ArrayList<>();

第一个成员可以实现组合模式,可构建一个非常复杂的模块,如上面的platform

第二个成员可以实现观察者模式,当模块的状态改变时,可以通知观察者。

4. 总结

  1. 模块以LifeCycle形式组合在一起,绑定在platform中,用户可很容易地剪裁/添加模块
  2. LifeCycle可很容易地控制模块的生命周期
  3. 初始化实质上就是初始化Facade,Facade模式可简化对内部服务的访问