您好,登錄后才能下訂單哦!
這篇文章主要介紹“elasticsearch插件如何實現類”,在日常操作中,相信很多人在elasticsearch插件如何實現類問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”elasticsearch插件如何實現類”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
elasticsearch 的 基礎類,主要分成 Component (組件) 和 Module (模塊)。
組件
CloseableComponent 可關閉組件
AbstractComponent 可配置組件
LifecycleComponent 活動可關閉組件
AbstractLifecycleComponent 可配置的活動可關閉組件 (。。。有點長)
模塊
Module 模塊
PreProcessModule 預處理模塊
SpawnModules 新模塊
一. AbstractPlugin 類 ,一個插件類要繼承自它或者實現Plugin接口
插件類需要實現的Plugin接口,每個方法所對應的組件類型是
modules() Module
services() LifecycleComponent
indexModules() Module
indexServices() CloseableIndexComponent
shardModules() Module
shardServices() CloseableIndexComponent
二. 現在插件實現類,有了,那他是怎么被加載到整個系統里面的呢?那就要請出我們插件組的各個成員了。
PluginManager類,插件管理類,負責插件的安裝,卸載,下載等工作。
PluginsHelper類,插件幫助類,負責列出環境下面所有的site插件。
PluginsService類,插件服務類,負責插件的加載,實例化和維護插件信息。
整個節點啟動的時候,InternalNode的構造方法里加載配置文件以后,首先會實例化 PluginsService 類,還有PluginsModule模塊 。
this.pluginsService = new PluginsService(tuple.v1(), tuple.v2()); this.settings = pluginsService.updatedSettings(); this.environment = tuple.v2(); CompressorFactory.configure(settings); NodeEnvironment nodeEnvironment = new NodeEnvironment(this.settings, this.environment); ModulesBuilder modules = new ModulesBuilder(); modules.add(new PluginsModule(settings, pluginsService)); modules.add(new SettingsModule(settings)); modules.add(new NodeModule(this));
PluginsService類的構造方法里,會開始加載插件類,從配置文件和Classpath里面,并且處理 plugin.mandatory 配置的強依賴插件,和模塊引用
public PluginsService(Settings settings, Environment environment) { super(settings); this.environment = environment; Map<String, Plugin> plugins = Maps.newHashMap(); //首先,我們從配置文件加載,默認的插件類 String[] defaultPluginsClasses = settings.getAsArray("plugin.types"); for (String pluginClass : defaultPluginsClasses) { Plugin plugin = loadPlugin(pluginClass, settings); plugins.put(plugin.name(), plugin); } // 現在, 我們查找,所有的在ClassPath下面的插件 loadPluginsIntoClassLoader(); plugins.putAll(loadPluginsFromClasspath(settings)); //加載JVM插件 Set<String> sitePlugins = PluginsHelper.sitePlugins(this.environment); //加載站點插件 //強制依賴的插件,如果沒有找到 String[] mandatoryPlugins = settings.getAsArray("plugin.mandatory", null); if (mandatoryPlugins != null) { Set<String> missingPlugins = Sets.newHashSet(); for (String mandatoryPlugin : mandatoryPlugins) { if (!plugins.containsKey(mandatoryPlugin) && !sitePlugins.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) { missingPlugins.add(mandatoryPlugin); } } if (!missingPlugins.isEmpty()) { //拋出異常,整個節點啟動失敗! throw new ElasticSearchException("Missing mandatory plugins [" + Strings.collectionToDelimitedString(missingPlugins, ", ") + "]"); } } logger.info("loaded {}, sites {}", plugins.keySet(), sitePlugins); this.plugins = ImmutableMap.copyOf(plugins); //現在,所有插件都加載好了,處理插件實現類的 onModule 方法的引用 ,這里有 依賴注入的秘密。 MapBuilder<Plugin, List<OnModuleReference>> onModuleReferences = MapBuilder.newMapBuilder(); for (Plugin plugin : plugins.values()) { List<OnModuleReference> list = Lists.newArrayList(); //.... } this.onModuleReferences = onModuleReferences.immutableMap(); this.refreshInterval = componentSettings.getAsTime("info_refresh_interval", TimeValue.timeValueSeconds(10)); }
PluginsService.info() 方法,是插件信息類,NodeService 會調用 ,是節點信息類的一部分,就是REST接口 /nodes 返回的內容
//PluginInfo類的字段 static final class Fields { static final XContentBuilderString NAME = new XContentBuilderString("name"); static final XContentBuilderString DESCRIPTION = new XContentBuilderString("description"); static final XContentBuilderString URL = new XContentBuilderString("url"); static final XContentBuilderString JVM = new XContentBuilderString("jvm"); static final XContentBuilderString SITE = new XContentBuilderString("site"); }
InternalNode 會繼續調用 modules.createInjector() 方法去實例化所有的模塊。PluginsModule模塊會去實例化和調用我們的插件
// 創建Plugin 類覆蓋 modules 方法的模塊 @Override public Iterable<? extends Module> spawnModules() { List<Module> modules = Lists.newArrayList(); Collection<Class<? extends Module>> modulesClasses = pluginsService.modules(); for (Class<? extends Module> moduleClass : modulesClasses) { modules.add(createModule(moduleClass, settings)); } modules.addAll(pluginsService.modules(settings)); return modules; } // 處理Plugin類實現了 onModule 方法的類 @Override public void processModule(Module module) { pluginsService.processModule(module); }
InternalNode 的 start()方法,就是節點啟動的時候,會啟動Plugin類覆蓋了services方法的服務
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) { injector.getInstance(plugin).start(); }
InternalIndicesService.createIndex() 方法,也就是創建索引的時候,會創建 Plugin類 覆蓋了 indexModules() 的模塊
InternalIndexService.createShard() 方法,創建分片的時候,會去創建Plugin類 覆蓋了 shardModules() 的模塊
同理刪除索引和分片的時候,會銷毀模塊和關閉服務。也就是插件擴展的服務和模塊是有3個生命周期的。
Global 節點級別
Index 索引級別
Shard 分片級別
三. 插件類有了,插件也被加載進系統了,那它是怎么擴展現有模塊服務的,那些模塊可以擴展,那些不可以?
可擴展的模塊,一般都提供了 addXXX,registerXXX 等方法
//智能提示 public void onModule(SuggestModule suggestModule) { suggestModule.registerSuggester(MySuggester.class); } //REST public void onModule(RestModule restModule) { restModule.addRestAction(MyRestAction.class); } //高亮 public void onModule(HighlightModule highlightModule) { highlightModule.registerHighlighter(MyHighlighter.class); }
可替換的模塊,一般是實現了SpawnModules接口的模塊,比如DiscoveryModule
@Override public Iterable<? extends Module> spawnModules() { Class<? extends Module> defaultDiscoveryModule; if (settings.getAsBoolean("node.local", false)) { defaultDiscoveryModule = LocalDiscoveryModule.class; } else { defaultDiscoveryModule = ZenDiscoveryModule.class; } return ImmutableList.of(Modules.createModule(settings.getAsClass("discovery.type", defaultDiscoveryModule, "org.elasticsearch.discovery.", "DiscoveryModule"), settings)); }
根據配置項discovery.type來確定加載那個模塊
不可以擴展或替換的組件,比如 Internal 開頭的組件,InternalClusterService,InternalIndicesService 等是不可以替換的。
到此,關于“elasticsearch插件如何實現類”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。