Elasticsearch客户端选型

一.背景

标准化NN服务端Elasticsearch组件的使用,减少开发接入成本,提高开发效率

 

二.技术选型

这里主要关注Elasticsearch客户端的选型,目前Elasticsearch客户端更新较快,主要分为两大类

官方ElasticStack客户端

    官方ElasticStack客户端分为以下几种

    1.Java Rest Client 

       Java Rest Client 分为 Java High Level Rest Client 和 Java Low Level Rest Client

       二者差异在于:

       Low Level Rest Client:提供了比较基础的操作,更接近 HTTP 协议的底层细节;

       High Level Rest Client:对底层的 HTTP 操作进行了更高层次的抽象。它通常基于低级别 Rest Client 构建,提供了更方便的接口,隐藏了一些 HTTP 协议的细节;(Elasticsearch高版本>7.1.x版本被Java API Client代替,但7.X以下仍然使用该客户端)

    2.Java API Client

       底层仍然是使用Java Low Level Rest Client,是目前ElasticStack官方主推的客户端,参考链接:https://github.com/elastic/elasticsearch-java,适配Elasticsearch7.X和8.X版本,支持,Lambda表达式,对于JSON格式的字段友好,API可读性较好
        

非官方ElasticStack客户端

    1. JEST 客户端

    https://github.com/searchbox-io/Jest  

    社区不活跃,更新慢,对高版本Elasticsearch支持度不好

    2. BBoss 客户端  

    https://esdoc.bbossgroups.com/#/

    基于Java High Level Rest Client封装的客户端,对不同版本的Elasticsearch支持度较好

    3. Spring data Elasticsearch

    Spring Data家族一员,基于 Java High Level Rest Client封装,更新速度较慢,目前使用过程中表示对于很多Elasticsearch API操作灵活度不高

总结

目前项目中使用的Elasticsearch版本是6.8.x,对于Elasticsearch API需要有深度使用,SpringDataElastisearch应对简单的增删改查这块没什么大问题,但对于Elasticsearch 客户端相关的配置可扩展的点不多,综上,考虑到版本原因,对于当前Elasticsearch 客户端的选型  High Level Rest Client 是相对较好的选择

 

三.API明细

1.条件配置类

由于考虑到需要集成到公共包,避免强叉对队友,同时避免不必要的Bean的初始化和实例化,这里使用JDK8 Conditional API来确保自动配置

import java.util.Iterator;

/**
 * RestHighLevelClient 配置是否加载条件类
 *
 * @author Sam.yang
 * @version 1.0
 * @date 2024-12-03 17:55
 */
public class ElasticsearchCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        if (environment instanceof StandardEnvironment) {
            MutablePropertySources mutablePropertySources = ((StandardEnvironment) environment).getPropertySources();
            return matchesElasticsearch(mutablePropertySources);
        }
        return false;
    }

    private boolean matchesElasticsearch(MutablePropertySources mutablePropertySources) {
        Iterator<PropertySource<?>> iterator = mutablePropertySources.iterator();
        for (Iterator<PropertySource<?>> it = iterator; it.hasNext(); ) {
            PropertySource propertySource = it.next();
            if (StringUtils.isNotBlank((CharSequence) propertySource.getProperty("elasticsearch.hosts"))) {
                return true;
            }
        }
        return false;
    }
}

2.Elasticsearch 客户端配置类

/**
 * @author Sam.yang
 * @version 1.0
 * @date 2024-12-03 17:55
 */
@Slf4j
@Data
@Configuration
@Conditional(value = ElasticsearchCondition.class)
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchClientConfig {

    /**
     * es host ip 地址(集群)
     */
    private String hosts;
    /**
     * es用户名
     */
    private String userName;
    /**
     * es密码
     */
    private String password;
    /**
     * es 请求方式
     */
    private String scheme;
    /**
     * es集群名称
     */
    private String clusterName;
    /**
     * es 连接超时时间
     */
    private Integer connectTimeOut;
    /**
     * es socket 连接超时时间
     */
    private Integer socketTimeOut;
    /**
     * es 请求超时时间
     */
    private Integer connectionRequestTimeOut;
    /**
     * es 最大连接数
     */
    private Integer maxConnectNum;
    /**
     * es 每个路由的最大连接数
     */
    private Integer maxConnectNumPerRouter;


    @Bean
    public RestHighLevelClient restHighLevelClient() {
        log.debug("初始化RestHighLevelClient开始");
        List<HttpHost> hostLists = Lists.newArrayList();
        String[] hostArr = hosts.split(",");
        for (String addr : hostArr) {
            String host = addr.split(":")[0];
            String port = addr.split(":")[1];
            hostLists.add(new HttpHost(host, Integer.parseInt(port), scheme));
        }
        RestClientBuilder builder = RestClient.builder(hostLists.toArray(new HttpHost[hostLists.size()]));
        //认证鉴权
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        if (!StringUtils.isEmpty(userName) && !StringUtils.isEmpty(password)) {
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
        }
        //连接延迟配置
        builder.setRequestConfigCallback(requestConfigCallback -> {
                    requestConfigCallback.setConnectTimeout(connectTimeOut);
                    requestConfigCallback.setSocketTimeout(socketTimeOut);
                    requestConfigCallback.setConnectionRequestTimeout(connectionRequestTimeOut);
                    return requestConfigCallback;
                }
        );
        //连接数配置
        builder.setHttpClientConfigCallback(httpClientConfigCallback -> {
                    httpClientConfigCallback.setMaxConnTotal(maxConnectNum);
                    httpClientConfigCallback.setMaxConnPerRoute(maxConnectNumPerRouter);
                    httpClientConfigCallback.setDefaultCredentialsProvider(credentialsProvider);
                    return httpClientConfigCallback;
                }
        );
        RestHighLevelClient client = new RestHighLevelClient(builder);
        log.debug("初始化RestHighLevelClient完成");
        return client;
    }
}

3.SpringBoot Yaml配置

elasticsearch:
  clusterName: elasticsearch
  hosts: xx.xx.xx.xx:9200
  scheme: http
  connectTimeOut: 1000
  socketTimeOut: 30000
  connectRequestTimeOut: 500
  maxConnectNum: 100
  maxConnectNumPerRoute: 100

 

posted @ 2025-08-26 23:11  听风是雨  阅读(58)  评论(0)    收藏  举报
/* 看板娘 */