背景:ElasticSearch:简单介绍以及使用Docker部署ElasticSearch 和 Kibana 这篇博客简单部署了ElasticSearch
ElasticSearch 客户端
特征
- 所有 Elasticsearch API 的强类型请求和响应。
- 所有 API 有阻塞和异步版本。
- 使用fluent的builders和功能模式,以便在创建复杂的嵌套结构时编写简洁且可读的代码。
- 通过使用对象映射器(如 Jackson)或任何 JSON-B 实现来无缝集成应用程序类。
- 将协议处理委托给 http 客户端(如Java Low Level REST Client),该客户端负责处理所有传输级别的问题:HTTP连接池、重试、节点发现等。
ElasticSearch 客户端安装要求
要求:
- Java 8 或更高版本。
- 一个 JSON 对象映射库,允许应用程序类与 Elasticsearch API 无缝集成。Java 客户端支持 Jackson 或JSON-B 库(如 Eclipse Yasson)。
ElasticSearch 连接
Java API 客户端围绕三个主要组件构建:
- API 客户端类。它们为 Elasticsearch API 提供了强类型数据结构和方法。由于 Elasticsearch API很大,因此它以feature 组(也称为"命名空间")构建,每个feature 组都有自己的客户端类。Elasticsearch核心功能在ElasticsearchClient类中实现。
- JSON 对象映射器。这会将您的应用程序类映射到 JSON,并将它们与 API 客户端无缝集成。
- 传输层实现。这是所有 HTTP 请求处理发生的地方。
此代码段创建这三个组件并将其连接在一起:
// Create the low-level client
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200)).build();
// Create the transport with a Jackson mapper
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
// And create the API client
ElasticsearchClient client = new ElasticsearchClient(transport);
身份验证由 Java Low Level REST Client管理。
Java Low Level REST Client
低级客户端的功能包括:
- 最小的依赖关系
- 跨所有可用节点的负载平衡
- 在节点发生故障时和特定响应代码时进行故障转移
- 失败的连接惩罚(是否重试失败的节点取决于它连续失败的次数;失败的尝试次数越多,客户端在再次尝试同一节点之前等待的时间就越长)
- 持久连接
- 跟踪请求和响应的日志记录
- 可选的自动发现群集节点(Sniffer)
身份验证
配置基本身份验证可以通过提供通过其构建器构建的时来完成。该接口有一个方法,该方法接收 org.apache.http.impl.nio.client.HttpAsyncClientBuilder 的实例作为参数,并具有相同的返回类型。可以修改 http 客户端生成器,然后返回该生成器。在以下示例中,我们设置了需要基本身份验证的默认凭据提供程序。
HttpClientConfigCallbackRestClient
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "test-user-password"));
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider);
}
});
可以禁用抢占式身份验证,这意味着每个请求都将在没有授权标头的情况下发送,以查看它是否被接受,并且在收到HTTP 401响应后,它将重新发送具有基本身份验证标头的完全相同的请求。如果您希望这样做,则可以通过以下方式禁用它来执行此操作:
HttpAsyncClientBuilder
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "test-user-password"));
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider);
}
});
测试
新建一个maven 项目
pom.xml 文件
elasticsearch 版本号要与自己部署的server 版本对应
<?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.xt</groupId>
<artifactId>elasticsearchdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.16.2</version>
</dependency>
<!-- elasticsearch 的客户端 和我部署的server相对应 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.16.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
Elasticsearch官方为Java提供了三种客户端API:
- TransportClient:这种方式通过TCP与Elasticsearch服务进行交互。还有 transport-netty4-client 的客户端
- Java Low Level REST Client:低级别的REST客户端,使用Apache HttpClient进行HTTP调用,简单封装了一下,通过http与集群交互,需要自己处理请求和响应,用户需自己编组请求JSON串,及解析响应JSON串。兼容所有ES版本。
- Java High Level REST Client:高级别的REST客户端,基于低级别的REST客户端,提供了面向方法的API,增加了编组请求JSON串、解析响应JSON串等相关api。使用的版本需要保持和ES服务端的版本一致,否则会有版本问题。同时请求参数和响应参数使用了elasticsearch定义的实体,方便从Java API Client迁移,Java High Level Rest Client完成elasticsearch请求响应实体转换为Java Low Level Rest Client的请求响应。即解决了Java API Client兼容问题,又解决了Java Low Level Rest Client封装使用问题
另外Spring框架也提供了spring-data-elasticsearch对Elasticsearch进行CURD操作,但是最底层也是基于Elasticsearch官方提供的API。
Spring Boot 框架的spring-boot-starter-data-elasticsearch 也是依赖于spring-data-elasticsearch和spring-boot-starter所建立起来的
连接ElasticSearch
public class ElasticsearchConnect {
public static void main(String[] args) throws IOException {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("xt", "xt"));
RestClientBuilder restClientBuilder = RestClient.builder(
new HttpHost("IP", 9200,"http"));
// 认证和线程数
restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
int threadCount = 10;
httpClientBuilder.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(threadCount).build());
return httpClientBuilder;
});
// 超时超时设置
restClientBuilder.setRequestConfigCallback(requestConfigCallback -> {
requestConfigCallback.setConnectTimeout(10);
requestConfigCallback.setSocketTimeout(10);
return requestConfigCallback;
});
// 创建客户端对象 虽然已经被弃用,但是了解基本使用还是没有问题 里面封装了RestClient
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
System.out.println(client);
// 关闭客户端连接
client.close();
}
}
关于ES 端口的说明
- 9200:使用http请求,所以我们的rest方式的client要使用这个端口进行访问
- 9300:使用tcp请求,是系统预留给es内部组件之间的通信方式
References:
- https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/installation.html#gradle
- https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/connecting.html
(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料、官方文档和自己的实践,整理的不足和错误之处,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源和分享的知识。)