天天看點

ElasticSearch es 插件開發

ElasticSearch es 插件開發

1. 插件分類

  • API Extension Plugins API擴充插件

    通過添加新的API或功能向Elasticsearch添加新功能,通常與搜尋或映射有關。

    優秀插件代表:

    SQL language Plugin: 讓 Elasticsearch 支援 SQL語句查詢 (by NLPchina)

  • Alerting Plugins 告警插件

    監控Elasticsearch索引情況,并在超過某個門檻值時觸發告警。

    優秀插件代表:

    X-Pack

  • Analysis Plugins 分析插件

    擴充索引的分析規則,比如各種分詞插件

    優秀插件代表:

    IK Analysis Plugin 中文分詞

    Japanese(Kuromoji) Analysis plugin 日文分詞

    PinyinAnalysis Plugin 拼音分詞

  • Discovery Plugins 發現插件

    通過添加可用于代替Zen Discovery的新發現機制來擴充Elasticsearch 。

  • Ingest Plugins 提取插件

    增強每個節點的功能。

    優秀插件代表:

    Ingest Attachment Processor Plugin 讓每個節點都可以處理附件檔案

  • Management Plugins 管理插件

    管理Es叢集

    優秀插件代表:X-Pack

  • Mapper Plugins 映射插件

    主要用來擴充es資料類型

  • Scripting Plugins 腳本插件

    主要用來擴充es的腳本功能,讓es支援使用其他腳本語言。

    優秀插件代表:

    JavaScript Language

    Python Language

  • Security Plugins 安全插件

    擴充es的安全政策,比如控制api的通路權限等

    優秀插件代表:X-Pack

  • Snapshot/Restore Repository Plugins 快照/還原存儲庫插件

    擴充es的快照和恢複功能

  • Store Plugins 存儲插件

    擴充es的存儲方式,es預設使用的是Lucene存儲資料的

    優秀插件代表:

    Store SMB Windows SMB

2. 插件開發

一 . 建立插件描述檔案

es插件描述檔案名為

plugin-descriptor.properties

放在

src/main/resources/

目錄下,内容如下

屬性 描述
name 插件名字
version 插件版本
description 插件功能描述
classname 插件入口class,完整路徑
java.version jdk 版本
elasticsearch.version elasticsearch 版本

内容如下,這裡都是引用項目的配置屬性

version=${project.version}
description=${project.description}
name=${es.plugin.name}
classname=${es.plugin.classname}
java.version=${es.plugin.java.version}
elasticsearch.version=${es.version}
           

二. pom.xml 配置,已經打包配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.caspar.es.plugin</groupId>
    <artifactId>es-plugin-hello</artifactId>
    <version>5.5.3</version>
    <name>es-plugin-hello</name>
    <description>My first es plugin</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <es.version>5.5.3</es.version>
        <es.plugin.name>es-plugin-hello</es.plugin.name>
        <es.plugin.classname>com.caspar.es.plugin.hello.HelloPlugin</es.plugin.classname>
        <es.plugin.java.version>1.8</es.plugin.java.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${es.version}</version>
            <scope>provided</scope>
        </dependency>


    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>*.properties</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptors>
                        <descriptor>src/main/assemblies/plugin.xml</descriptor>
                    </descriptors>
                    <finalName>es-plugin-hello</finalName>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
           

plugin.xml

裡面配置zip的打包配置

<?xml version="1.0"?>
<assembly>
    <id>release</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/elasticsearch/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <useTransitiveDependencies>true</useTransitiveDependencies>
        </dependencySet>
    </dependencySets>
    <files>
        <file>
            <source>target/classes/plugin-descriptor.properties</source>
            <outputDirectory>/elasticsearch/</outputDirectory>
        </file>
        <file>
            <source>src/main/resources/plugin-security.policy</source>
            <outputDirectory>/elasticsearch/</outputDirectory>
        </file>
    </files>
</assembly>
           

三. 插件入口開發

插件入口需要繼承Plugin類,然後實作相應的插件類型接口,去做相應的處理。我們這裡實作ActionPlugin接口 實作一個api的插件類型,需要重寫getRestHandlers方法,并将自己處理業務邏輯的handler類注冊進去

HelloPlugin

内容

package com.caspar.es.plugin.hello;

import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.IndexScopedSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;

import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

/**
 * @author caspar.chen
 * @date 2018/9/16
 **/
public class HelloPlugin extends Plugin implements ActionPlugin {


    @Override
    public List<RestHandler> getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
        return Collections.singletonList(new HelloHandler(settings, restController));
    }

}
           

四. 插件處理Handler,處理具體業務邏輯

HelloHandler

内容

package com.caspar.es.plugin.hello;

    import org.elasticsearch.client.node.NodeClient;
    import org.elasticsearch.common.settings.Settings;
    import org.elasticsearch.common.xcontent.XContentBuilder;
    import org.elasticsearch.rest.*;

    import java.io.IOException;
    import java.util.Date;

    /**
     * @author caspar
     * @date 2018/9/16
     **/
    public class HelloHandler extends BaseRestHandler {

        protected HelloHandler(Settings settings, RestController restController) {
            super(settings);
            //api的url映射
            restController.registerHandler(RestRequest.Method.GET, "/_hello", this);
        }


        @Override
        protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient nodeClient) throws IOException {
            //接收的參數
            System.out.println("params==" + restRequest.params());

            long t1 = System.currentTimeMillis();

            String name = restRequest.param("name");

            long cost = System.currentTimeMillis() - t1;
            //傳回内容,這裡傳回一個處理業務邏輯的發費時間,前端傳的name,以及目前時間。
            return channel -> {
                XContentBuilder builder = channel.newBuilder();
                builder.startObject();
                builder.field("cost", cost);
                builder.field("name", name);
                builder.field("time", new Date());
                builder.endObject();
                channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder));
            };
        }

    }
           

開發好後,執行maven打包,會在target目錄生成相應的zip檔案。這個就是我們需要的插件包,後面安裝插件會用到。

3. 插件管理

  • 檢視安裝的插件清單

    使用

    list

    參數列出安裝的所有插件
  • 安裝插件

    使用

    install

    參數安裝插件
    • es 團隊維護的核心插件,直接用插件名安裝
    • 安裝網絡上的插件,直接填url位址
    • 安裝本地插件,file:// + 本地zip檔案位址
      bin/elasticsearch-plugin install 'file:///path/to/plugin.zip'
                 
  • 更新插件

    remove

    install

    bin/elasticsearch-plugin remove 'plugin name'
    bin/elasticsearch-plugin install 'plugin name'
               

測試插件效果

安裝好插件後,需要重新開機elasticsearch,并且要在每個node上安裝重新開機才有效

安裝好後在kibana或者curl

GET _hello?name=caspar

會看到傳回結果

{
  "cost": ,
  "name": "caspar",
  "time": "2018-09-16T06:09:33.199Z"
}