Elasticsearch技术解析与实战
上QQ阅读APP看书,第一时间看更新

1.6.1 Java接口说明

可以把Java开发看成CS模式,即客户端请求,服务端响应,所有的操作是完全异步的。此外在客户端上操作,很多的操作可以在客户端上来完成,增加了系统效率。Java客户端和服务端都是使用相同的程序。在5.0.0版本中,增加了单独的HTTP REST客户端。

1.mvn仓库配置

在mvn项目中可以在pom.xml增加mvn仓库,如下所示。

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

打成独立的jar包。如果你想打成独立的jar包,并包含所有的依赖。不能使用mvn的maven-assembly-plugin插件,因为它不能很好地处理META-INF/services结构。我们可以用maven-shade-plugin插件来进行打包。例如:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals><goal>shade</goal></goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
        </transformers>
      </configuration>
    </execution>
  </executions></plugin>

如果你有一个main函数,可以通过调用java-jar yourjar.jar运行时,只需要在插件配置中加入一句话。例如:

<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
  <mainClass>com.secisland.es.demo.main</mainClass>
</transformer>

可以使用多种方式来调用Java客户端。一种方式是把节点加入集群,不存储数据。另一种是把节点作为客户端连接到集群。

警告 客户端版本要和集群版本一致,否则有可能出现不可预知的错误。

2.嵌入式节点客户端

实例化一个基于节点的客户,这是对Elasticsearch执行操作的最简单的方法。例如:

import static org.elasticsearch.node.NodeBuilder.*;
// on startup
Node node = nodeBuilder().node();
Client client = node.client();
// on shutdown
node.close();

当你开始一个节点,它加入了一个Elasticsearch集群。你可以通过设置cluster.name来配置不同的集群,或显式使用clusterName方法来创建对象。在项目工程中可以定义cluster.name,配置在/src/main/resources/elasticsearch.yml文件中。只要在classpath中能找到elasticsearch.yml文件,节点启动的时候就会加载此文件。配置文件中定义:

cluster.name: secilog

或者在Java代码中指定:

Node node = nodeBuilder().clusterName("secilog").node();
Client client = node.client();

使用客户端的好处是依赖Elasticsearch服务端的特性把需要执行的操作自动路由到节点,当加入集群节点作为客户端时,最重要的是不能在此节点上增加数据保存,这可以通过配置来完成。把node.data设置为false,或将node.client设置为true。这都可以通过NodeBuilder的方法来实现。

import static org.elasticsearch.node.NodeBuilder.*;
// on startup
// 嵌入式节点可以不用打开http端口
Node node =
  nodeBuilder()
    .settings(Settings.settingsBuilder().put("http.enabled" false))
    .client(true)
  .node();
Client client = node.client();
// on shutdown
node.close();

另一个常见的客户端用处是用在单元/集成测试中。在这种情况下,只需要启动一个“本地”(local)节点。这里的local节点的意思是公用一个Java虚拟机。在这种情况下两个服务会互相发现自己并形成一个集群。例如:

import static org.elasticsearch.node.NodeBuilder.*;
// on startup
Node node = nodeBuilder().local(true).node();
Client client = node.client();
// on shutdown
node.close();

嵌入式节点的缺点是:

□频繁启动和停止一个或多个节点在集群上会创建不必要的噪声。

□就像其他节点一样嵌入式节点客户端会响应外部请求。

注意 用Eclipse开发的时候有可能会报错:

Exception in thread "main" java.lang.IllegalStateException: path.home is not configured

解决方法:在main方法的类中选择run configurations,在Arguments标签页下的vm arguments输入:-Des.path.home=-Des.path.home即可。例如:

-Des.path.home=D:\elasticsearch-2.2.0

3.通过连接的客户端

客户端通过TransportClient对象可以使用远程连接的方式连接Elasticsearch集群。这种情况下不用加入集群,比较像传统的CS程序的架构,如数据库连接。例如:

// on startup
Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("host1") 9300))
  .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("host2") 9300));
// on shutdown
client.close();

注意,如果集群名称不是“Elasticsearch”,你必须设置集群名称或者使用elasticsearch.yml配置文件在客户端工程中配置。可以连接一个集群中的多个节点。

Settings settings = Settings.settingsBuilder()
        .put("cluster.name" "secilog").build();
Client client = TransportClient.builder().settings(settings).build();

可以设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其他机器的IP地址加到客户端中。这样做的好处是一般你不用手动设置集群里所有集群的IP到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。

Settings settings = Settings.settingsBuilder()
                    .put("client.transport.sniff" true).build();
TransportClient client = TransportClient.builder().settings(settings).build();

其他参数说明如下:

□client.transport.ignore_cluster_name:设置为true的时候忽略连接节点时的集群名称验证。

□client.transport.ping_timeout:等待一个节点的ping响应的时间,默认5秒。

□client.transport.nodes_sampler_interval:监听和连接节点的频率(时间间隔),默认5秒。