利用Java API连接不同版本的ElasticSearch,方法是不一样的,本文只介绍主流的方法。
#####无论如何请确保Client的版本和ElasticSearch集群版本保持一致,否则有可能出现不可预知的错误#####
(1)Node Client(java语言版本,已经在2.3版本中已经弃用)
(2)Transport Client(只能在ElasticSearch2.x 5.x使用,7.x将过时,8.x将被弃用)
官网说明:TransportClient
(3)JestClient
(4)Spring data elasticsearch或者Spring boot elasticsearch
参考:https://github.com/spring-projects/spring-data-elasticsearch
(5)Java Low Level REST Client (5.0版本开始加入,建议5.x之后可用)
官网说明:Java REST Client
Elasticsearch的官方low-level客户端。 它允许通过http与Elasticsearch集群进行通信。 不会对请求进行编码和响应解码。 它与所有Elasticsearch版本兼容。包含功能:
(6)Java High Level REST Client( 5.6.0版本开始加入,建议6.x之后可用)
官网说明:Java REST Client
elasticsearch的官方high-level客户端,基于low-level客户端,它公开了API特定的方法,并负责处理。
high-level客户端的API 、特性、方法不很完善,但是可以使用low-level基于json发送请求代替。
ElasticSearch主流使用时5.x 6.x,针对代码实现部分,接下来分别按照5.x 和 6.x做实现
TransportClient
public class TransportClient {
private static final String CLUSTER_NAME = ConfigUtils.getEsClusterName();
private static final String CLUSTER_CLIENT_TRANSPORTSNIFF = ConfigUtils.getClientTransportSniff();
private static final String CLUSTER_HOSTNAME_PORT = ConfigUtils.getEsClusterDiscoverHostName();
private static Client client;
public static Client getClient() {
if (client == null) {
String hostnamesPort[] = CLUSTER_HOSTNAME_PORT.split(",");
Settings settings = Settings.builder()
/*设置ES实例的名称*/
.put("cluster.name", CLUSTER_NAME)
/*自动嗅探整个集群的状态,把集群中其他ES节点的ip添加到本地的客户端列表中*/
.put("client.transport.sniff", CLUSTER_CLIENT_TRANSPORTSNIFF)
.build();
/*初始化client*/
org.elasticsearch.client.transport.TransportClient transportClient = new PreBuiltTransportClient(settings);
String host;
int port;
String[] temp;
if (null != hostnamesPort) {
for (String hostPort : hostnamesPort) {
try {
temp = hostPort.split(":");
host = temp[0].trim();
port = Integer.parseInt(temp[1].trim());
transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
client = transportClient;
}
return client;
}
具体参考:
https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch5.x/src/main/java/com/elastic/transprotclient
* Client内部已经实现连接池,不需要手动close
* 杜绝运行一段时间内不造成资源耗尽而无法创建连接
* 对于频繁连接集群时,最好使用单例模式
(1)Java REST Client(Java Low Level Rest Client)
public class LowLevelClient {
private static final String CLUSTER_HOSTNAME_PORT = ConfigUtils.getEsClusterDiscoverHostName();
public static RestClient getClient() {
String hostnamesPort[] = CLUSTER_HOSTNAME_PORT.split(",");
String host;
int port;
String[] temp;
RestClientBuilder restClientBuilder = null;
if (null != hostnamesPort) {
for (String hostPort : hostnamesPort) {
temp = hostPort.split(":");
host = temp[0].trim();
port = Integer.parseInt(temp[1].trim());
restClientBuilder = RestClient.builder(new HttpHost(host, port, "http"));
}
}
return restClientBuilder.build();
}
具体参考:
https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch6.x/src/main/java/com/elastic/client/lowlevelclient
(2) Java High Level REST Client
https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch6.x/src/main/java/com/elastic/client/highlevelclient
x-pack是Elastic官方推荐的,具有监控、安全认证,监控、机器学习、图形等功能。x-pack加入后,使用Java API连接集群,需要增加部分代码:
//安装x-pack后的初始化方法
Settings settings = Settings.builder()
//集群名
.put("cluster.name", clusterName)
.put("client.transport.sniff", true)
.put("xpack.security.transport.ssl.enabled", false)
//x-pack用户密码 elastic:changme是默认的用户名:密码
.put("xpack.security.user", "elastic:changme")
.build();
用哪个好?
这当然必须根据业务来选择,如果业务比较简单,随便哪个都可以,不过不建议使用原生的NodeClient;
(1)若集群是ElasticSearch5.x建议使用TransportClient
完善的API依旧是 TransportClient的优势;
基于java api封装的orm框架,封装比较死板,不太灵活,兼容性差,不能像调用restful那样直接操作query dsl,所以也不能直接针对query dsl,在head插件或者kibana里面调试和调优query dsl,写出了query dsl还要想方设法转换成对应的java api的调用方式;
(2)若集群是ElasticSearch6.x建议使用RestClient
RestClient,虽然当前API可能不是很完整,但是这是趋势;
基于restful的,直接操作各种restful api和query dsl,比较简单,没有orm功能;
(3)Spring框架或SpringBoot框架
如果业务基于spring框架开发,使用spring-data-elasticsearch也是可以的,参考:https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch5.x/src/main/java/com/elastic/springdataclient