服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - elasticsearch通过guice注入Node组装启动过程

elasticsearch通过guice注入Node组装启动过程

2022-11-16 14:49zziawan Java教程

这篇文章主要为大家介绍了 elasticsearch通过guice注入Node组装启动过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

elasticsearch启动过程

elasticsearch的启动过程是根据配置和环境组装需要的模块并启动的过程。这一过程就是通过guice注入各个功能模块并启动这些模块,从而得到一个功能完整的node。正如之前所说elasticsearch的模块化特点,它的各个功能都是独立实现,然后实现通过guice对外提供。

首先简单的说一下guice,它是google的一个轻量级依赖注入框架。它的作者也是依赖注入标准(JSR-330)制定者。虽然它是轻量级框架,但是它的功能及性能却非常好,这也是elasticsearch选用它作为代码主要框架的一个主要原因。它的使用请参考它的用户指导。

首先看一下node的初始化

node接口的唯一实现是InternalNode,它的初始化代码如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public InternalNode(Settings preparedSettings, boolean loadConfigSettings) throws ElasticsearchException {
        final Settings pSettings = settingsBuilder().put(preparedSettings)
                .put(Client.CLIENT_TYPE_SETTING, CLIENT_TYPE).build();
        Tuple<Settings, Environment> tuple = InternalSettingsPreparer.prepareSettings(pSettings, loadConfigSettings);
        tuple = new Tuple<>(TribeService.processSettings(tuple.v1()), tuple.v2());
        logger.info("initializing ...");
       //启动插件service,加载并启动插件
        this.pluginsService = new PluginsService(tuple.v1(), tuple.v2());
        this.settings = pluginsService.updatedSettings();
        // create the environment based on the finalized (processed) view of the settings
        this.environment = new Environment(this.settings());
        CompressorFactory.configure(settings);
       //配置node环境
        final NodeEnvironment nodeEnvironment;
        try {
            nodeEnvironment = new NodeEnvironment(this.settings, this.environment);
        } catch (IOException ex) {
            throw new ElasticsearchIllegalStateException("Failed to created node environment", ex);
        }
        boolean success = false;
        try {
       //加载各个模块
            ModulesBuilder modules = new ModulesBuilder();
            modules.add(new Version.Module(version));
            modules.add(new CacheRecyclerModule(settings));
            modules.add(new PageCacheRecyclerModule(settings));
            modules.add(new CircuitBreakerModule(settings));
            modules.add(new BigArraysModule(settings));
            modules.add(new PluginsModule(settings, pluginsService));
            modules.add(new SettingsModule(settings));
            modules.add(new NodeModule(this));
            modules.add(new NetworkModule());
            modules.add(new ScriptModule(settings));
            modules.add(new EnvironmentModule(environment));
……
}

可以看到node的初始化过程主要包括三部分

第一是启动插件服务(es提供了插件功能来进行扩展功能,这也是它的一个亮点),加载需要的插件

第二是配置node环境

最后就是通过guice加载各个模块。

启动各个模块的过程

插件服务稍微复杂最后再说。elasticsearch各个功能模块实现的非常好,解耦非常完美,很多模块都实现了生命周期接口,只有启动它才能够对外提供服务,它的启动过程也是功能模块初始化的过程。因此,node节点的启动过程也就是这些模块初始化的过程。如下面的代码片段所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Node start() {
        if (!lifecycle.moveToStarted()) {
            return this;
        }// hack around dependency injection problem (for now...)
        injector.getInstance(Discovery.class).setAllocationService(injector.getInstance(AllocationService.class));
        for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
            injector.getInstance(plugin).start();
        }
    //通过guice获取各个模块的service接口并启动
        injector.getInstance(MappingUpdatedAction.class).start();
        injector.getInstance(IndicesService.class).start();
        injector.getInstance(IndexingMemoryController.class).start();
        injector.getInstance(IndicesClusterStateService.class).start();
        injector.getInstance(IndicesTTLService.class).start();
        injector.getInstance(RiversManager.class).start();
        injector.getInstance(SnapshotsService.class).start();
        injector.getInstance(TransportService.class).start();
……
}

每个模块service都会实现一个start接口,模块功能初始化过程都是这这个函数中实现。每个模块的具体启动过程后面会有涉及,这里就不做深入分析。

插件的加载过程

每个node在加载各个模块前,会首先加载所需要的插件,如果有些插件加载不成功node会启动失败。这里会加载三类插件:首先是配置插件,配置到节点配置文件中插件,如分词插件等;然后查找classpath中能找到的插件,这些插件一般防止在plugin文件夹中;最后是加载site插件,site插件是不涉及java代码的纯网站式插件,如监控插件head,bigdesk等。任何使用者都可以开发自己需要的插件,只要按着elasticsearch相关版本的插件开发规范来实现即可。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public PluginsService(Settings settings, Environment environment) {
        super(settings);
        this.environment = environment;
        ……
        ImmutableList.Builder<Tuple<PluginInfo, Plugin>> tupleBuilder = ImmutableList.builder();
        // 加载配置插件
        String[] defaultPluginsClasses = settings.getAsArray("plugin.types");
        for (String pluginClass : defaultPluginsClasses) {
            Plugin plugin = loadPlugin(pluginClass, settings);
            PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), hasSite(plugin.name()), true, PluginInfo.VERSION_NOT_AVAILABLE);
            if (logger.isTraceEnabled()) {
                logger.trace("plugin loaded from settings [{}]", pluginInfo);
            }
            tupleBuilder.add(new Tuple<>(pluginInfo, plugin));
        }
        // 查找classpatch中的所有插件
        loadPluginsIntoClassLoader();
        if (loadClasspathPlugins) {
            tupleBuilder.addAll(loadPluginsFromClasspath(settings));
        }
        this.plugins = tupleBuilder.build();
        // We need to build a List of jvm and site plugins for checking mandatory plugins
        Map<String, Plugin> jvmPlugins = Maps.newHashMap();
        List<String> sitePlugins = Lists.newArrayList();
        for (Tuple<PluginInfo, Plugin> tuple : this.plugins) {
            jvmPlugins.put(tuple.v2().name(), tuple.v2());
            if (tuple.v1().isSite()) {
                sitePlugins.add(tuple.v1().getName());
            }
        }
        // 加载site插件
        ImmutableList<Tuple<PluginInfo, Plugin>> tuples = loadSitePlugins();
        for (Tuple<PluginInfo, Plugin> tuple : tuples) {
            sitePlugins.add(tuple.v1().getName());
        }
        // 检验代理插件,如果有加载不成功的插件就抛出异常,停止node启动。
        String[] mandatoryPlugins = settings.getAsArray("plugin.mandatory", null);
        if (mandatoryPlugins != null) {
            Set<String> missingPlugins = Sets.newHashSet();
            for (String mandatoryPlugin : mandatoryPlugins) {
                if (!jvmPlugins.containsKey(mandatoryPlugin) && !sitePlugins.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) {
                    missingPlugins.add(mandatoryPlugin);
                }
            }
            if (!missingPlugins.isEmpty()) {
                throw new ElasticsearchException("Missing mandatory plugins [" + Strings.collectionToDelimitedString(missingPlugins, ", ") + "]");
            }
        }
……
}

以上就是pluginservice的初始化过程,在它的初始化过程中,加载所有能够找的插件。插件的启动在其他功能模块之前,些插件,如分词插件,启动不成功则会对节点的功能造成影响,因此会在这里就中断节点的启动过程让用户知道。这就是节点的启动过程。插件加载成功,各个功能模块加载并启动成功,节点就启动成功。

限于篇幅这里模块相关详情都没有进行深入在接下来模块分析中会一一分析,希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/zziawanblog/p/6502928.html

延伸 · 阅读

精彩推荐
  • Java教程java TreeMap源码解析详解

    java TreeMap源码解析详解

    这篇文章主要介绍了java TreeMap源码解析详解的相关资料,需要的朋友可以参考下...

    Walker_YAM3092020-09-06
  • Java教程Mybatis中输入输出映射与动态Sql图文详解

    Mybatis中输入输出映射与动态Sql图文详解

    这篇文章主要给大家介绍了关于Mybatis中输入输出映射与动态Sql的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习...

    风沙迷了眼8392021-07-15
  • Java教程Java扫描文件夹下所有文件名

    Java扫描文件夹下所有文件名

    这篇文章主要为大家详细介绍了Java扫描文件夹下所有文件名,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    qq_3837562010272021-04-02
  • Java教程Java深入浅出掌握SpringBoot之MVC自动配置原理篇

    Java深入浅出掌握SpringBoot之MVC自动配置原理篇

    在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制,只有把这些都搞清楚了,我们在之...

    龍弟-idea5612022-03-02
  • Java教程java的反射用不好试试内省?

    java的反射用不好试试内省?

    使用内省相对于直接使用反射更加安全可靠,Java的反射机制比较特殊,它不同于一般的编程方式,稍不小心就容易破坏类的封装性。练的不好,就容易走火...

    二当家的白帽子9552021-10-15
  • Java教程Spring中WebDataBinder使用详解

    Spring中WebDataBinder使用详解

    这篇文章主要为大家详细介绍了Spring中WebDataBinder的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    无名小卒升级中8222020-11-28
  • Java教程让Java程序自动重启的实现方法(推荐)

    让Java程序自动重启的实现方法(推荐)

    下面小编就为大家带来一篇让Java程序自动重启的实现方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Java之家6452020-08-26
  • Java教程MybatisPlus中@TableField注解的使用详解

    MybatisPlus中@TableField注解的使用详解

    这篇文章主要介绍了MybatisPlus中@TableField注解的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    BADAO_LIUMANG_QIZHI26382020-09-09