共計 5703 個字符,預計需要花費 15 分鐘才能閱讀完成。
這篇文章主要介紹“elasticsearch 插件如何實現類”,在日常操作中,相信很多人在 elasticsearch 插件如何實現類問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”elasticsearch 插件如何實現類”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!
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 插件如何實現類”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!