Elasticsearch:使用 Low Level Java 客户端来创建连接 – Elastic Stack 8.x
2022年8月25日 | by mebius
由于在 Elastic Stack 8.x 中天然地添加了安全性,我们在使用 Java 客户端进行连接的时候,我们可以通过不同的途径来完成。在我之前的文章中,我创建了一系列的文章来展示:
- Elasticsearch:使用最新的 Elasticsearch Java client 8.0 来创建索引并搜索
- Elasticsearch:使用 Elasticsearch Java client 8.0 来连接带有 HTTPS 的集群
- Elasticsearch:使用标准 Java HTTP 的集成 – Elastic Stack 8.x
- Elasticsearch:如何在 Java 应用中创建 mappings 及进行批量写入
在上面,我们可以通过 Java HTTP 的集成来访问 Elasticsearch。这个是不依赖于 Elasticsearch 的版本来进行访问的。我们也可以通过 Elastic 公司所提供的 Elasticsearch Java client 8.x 来进行访问。在通常的情况下,Elasticsearch Java client 会更为高效。它提供了良好的 JSON 支持以及对连接的管理。这样也是被推荐的方法。
在今天的文章中,我将使用另外一种方式来进行展示。我将使用 Low Level client API 来进行连接及访问。
安装
如果你还没有安装好自己的 Elasticsearch 及 Kibana。请参阅我之前的文章:
- 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
- Kibana:如何在 Linux,MacOS 及 Windows上安装 Elastic 栈中的 Kibana
- Elasticsearch:设置 Elastic 账户安全
在默认的情况下,Elastic Stack 8.x 的安装已带有安全。如果你是自托管型的集群,那么你的证书应该是自签名的证书。
创建 Low Level Elasticsearch 客户端
有两个官方的 tgcodeElasticsearch 客户端:低级客户端和 Elasticsearch 8.x (https://github.com/elastic/elasticsearch-java) 提供的新类tgcode型客户端。 低级用于与 Elasticsearch 通信,主要特点如下:
- 最小依赖
- 跨所有可用节点的负载平衡
- 在节点故障和特定响应代码的情况下进行故障转移
- 失败的连接惩罚(失败的节点是否重试取决于它连续失败的次数;失败的尝试越多,客户端在再次尝试同一节点之前等待的时间越长)
- 持久连接
- 跟踪请求和响应的日志记录
- 集群节点的可选自动发现
要创建 RestClient,我们将执行以下步骤:
1)我们需要添加用于执行 HTTP 调用的 Elasticsearch HTTP 客户端库。 该库位于 search.maven.org 的主 Maven 存储库中。 要在 Maven pom.xml 项目中启用编译,只需添加以下代码:
pom.xml
4.0.0
org.example
ELasticsearchJava-lowlevel
1.0-SNAPSHOT
8
8
org.elasticsearch.client
elasticsearch-rest-client
8.0.0
2)如果我们想实例化一个客户端并使用 get 方法获取一个文档,代码将如下所示:
ElasticsearchJavaLowLevel.java
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.
HttpAsyncClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.*;
import java.io.IOException;
import java.security.*;
import javax.net.ssl.SSLContext;
public class ElasticsearchJavaLowLevel {
public static void main(String[] args) throws
KeyManagementException, NoSuchAlgorithmException,
KeyStoreException {
RestClientBuilder clientBuilder = RestClient.
builder(new HttpHost("localhost", 9200, "https"))
.setCompressionEnabled(true);
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(System.
getenv("ES_USER"), System.getenv("ES_PASSWORD")));
final SSLContext sslContext = new
SSLContextBuilder().loadTrustMaterial(null,
TrustAllStrategy.INSTANCE).build();
clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder
customizeHttpClient(HttpAsyncClientBuilder
httpClientBuilder) {
return httpClientBuilder
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setDefaultCredentialsProvider(credentialsProvider);
}
});
RestClient client = clientBuilder.build();
try {
Request request = new Request("GET", "/mybooks/_doc/1");
Response response = client.
performRequest(request);
if (response.getStatusLine().getStatusCode()
!= HttpStatus.SC_OK) {
System.err.println("Method failed: " +
response.getStatusLine());
} else {
HttpEntity entity = response.getEntity();
String responseBody = EntityUtils.
toString(entity);
System.out.println(responseBody);
}
} catch (IOException e) {
System.err.println("Fatal transport error: "
+ e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们需要在环境变量中设置你访问 Elasticsearch 集群的用户名及密码。
上面的代码实现的功能相当于我们在 Kibana 下打入如下的命令:
GET mybooks/_doc/1
为了能够让上面的代码顺利执行,我们首先在 Kibana 中创建如下的一个索引:
PUT mybooks/_doc/1
{
"uuid": "1",
"title": "Great math"
}
解释
在内部,Elasticsearch RestClient 客户端使用 Apache HttpComponents 库并用更方便的方法包装它。如果你想了解如何使用 Apache HttpComponents 来建立和 Elasticsearch 的连接,请参考我之前的文章 “Elasticsearch:使用标准 Java HTTP 的集成 – Elastic Stack 8.x”。 我们执行了前面的步骤来创建和使用 RestClient。 让我们更详细地看一下它们:
1)第一步是初始化 RestClient 对象。 这是通过以下代码片段完成的:
RestClientBuilder clientBuilder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
// some stuff to setup SSL and auth as seen in previous
example
…
RestClient client = clientBuilder.build();
builder 方法接受一个多值 HttgcodetpHost 主机(通过这种方式,你可以传递一个 HTTP 地址列表)并在后台返回 RestClientBuilder。
2)RestClientBuilder 对象允许通过多种方法自定义客户端通信,例如:
- setDefaultHeaders(Header[] defaultHeaders):这允许必须为要提供的每个请求发送的自定义标头。
- setMaxRetryTimeoutMillis(int maxRetryTimeoutMillis):如果对同一请求有多次尝试,这允许定义最大重试超时。
- setPathPrefix(String pathPrefix):这允许为每个请求定义自定义路径前缀。
- setFailureListener(FailureListener failureListener):这允许提供自定义故障侦听器,在节点故障实例中调用该侦听器。 这可用于在节点故障的情况下提供用户定义的行为。
- setHttpClientConfigCallback(RestClientBuilder.HttpClientConfigCallback httpClientConfigCallback):这允许修改 HTTP 客户端通信,例如添加压缩或加密层。
- setRequestConfigCallback(RestClientBuilder.RequestConfigCallback requestConfigCallback):这允许配置请求身份验证、超时和其他可以在请求级别设置的属性。
3)创建 RestClient 后,我们可以通过几种 performRequest 方法对它执行一些请求,用于同步调用和 performRequestAsync 方法用于异步调用。这些方法允许你设置参数,例如:
- String method:这是要在调用中使用的 HTTP 方法或动词(必需)。
- String endpoint:这是 API 端点(必需)。 在前面的示例中,它是 /test-index/_doc/1。
- Map params:这是要作为查询参数传递的值的映射。
- HttpEntity entity:这是请求的正文。 它是 org/apache/http/HttpEntity(有关更多详细信息,请参阅HttpEntity – httpcore 4.4.15 javadoc)。
- HttpAsyncResponseConsumer 响应消费者:
这用于管理异步请求中的响应(请参阅 HttpAsyncResponseConsumer (Apache HttpCore NIO 4.4.14 API)了解更多详细信息)。 默认情况下,它用于将所有响应保存在堆内存中(内存上限为 100 MB)。 - ResponseListener responseListener:这用于在异步调用期间注册回调。
- Header…header:这些是在调用期间传递的附加 header。
在前面的示例中,我们使用以下代码执行了 GET REST 调用:
Response response = client.performRequest(request);
响应对象是 org.elasticsearch.client.Response,它包装了 Apache HttpComponents 响应。
运行上面的代码,我们可以看到的结果为:
{"_index":"mybooks","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{
"uuid": "1",
"title": "Great math"
}
}
我们可以看到它的结果和我们之前的是没有什么不同。
文章来源于互联网:Elasticsearch:使用 Low Level Java 客户端来创建连接 – Elastic Stack 8.x
相关推荐: Elasticsearch:使用不同的 CA 更新安全证书 (一)
如果你必须添加组织中的新 CA 证书,或者你需要自己生成新 CA,请使用此新 CA 签署新节点证书并指示你的节点信任新 CA 证书。在今天的展示中,我将来演示如何更新一个 Elasticsearch 8.x 集群的 CA 证书。 Elasticsearch:使…