前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Elasticsearch High Level Rest Client

Elasticsearch High Level Rest Client

作者头像
程序猿杜小头
发布2022-12-01 21:33:06
7330
发布2022-12-01 21:33:06
举报
文章被收录于专栏:程序猿杜小头程序猿杜小头

Elasticsearch High Level Rest Client

Elasticsearch自身暴露了一套REST API,可以直接调用它们来配置和访问Elasticsearch。为了方便各类语言与REST API交互,官方提供若干客户端组件,这类似于一套SDK;有了这套SDK,首先,不再需要显式地编写REST API的URL信息,只需要传入参数和解析响应即可;其次,SDK层封装了异步API,可以更方便地进行异步编程。

Elasticsearch有三个版本的Java Client,分别是:

  • TransportClient
  • High Level Rest Client
    • index(IndexRequest)
    • delete(DeleteRequest)
    • update(UpdateRequest)
    • get(GetRequest)
    • search(SearchRequest)
    • ···
  • Low Level Rest Client
    • performRequest(Request)

TransportClient已经废弃,官方会在Elasticsearch 8.0中彻底移除它。High Level Rest Client在Low Level Rest Client基础上构建,而Low Level Rest Client底层依赖于Apache HttpClient组件。High Level Rest Client对REST API中的接口单独封装,可以构建多种Request对象,较为灵活;而Low Level Rest Client仅仅暴露performRequest(),也就是说该方法承载了REST API中所有的逻辑。

1 依赖引入

强烈建议 客户端组件与Elasticsearch版本保持一致

代码语言:javascript
复制
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.9.1</version>
    <exclusions>
        <exclusion>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.9.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.9.1</version>
</dependency>

2 使用方法

2.1 配置

代码语言:javascript
复制
spring.elasticsearch.rest.uris=A.B.C.D:9200,A.B.C.E:9200,A.B.C.F:9200
spring.elasticsearch.rest.read-timeout=15S
spring.elasticsearch.rest.connection-timeout=15S
spring.elasticsearch.rest.username=elastic
spring.elasticsearch.rest.password=ENC(P9fUyEbC+VN6OJtexPVLEd5+QF0h5c2A)

对应配置类模型如下:

代码语言:javascript
复制
@ConfigurationProperties(prefix = "spring.elasticsearch.rest")
public class ElasticsearchRestClientProperties {
    private List<String> uris = new ArrayList<>(Collections.singletonList("http://localhost:9200"));

    private String username;

    private String password;

    private Duration connectionTimeout = Duration.ofSeconds(1);

    private Duration readTimeout = Duration.ofSeconds(30);
}

2.2 注入RestHighLevelClient实例

你只需要像下面这样在业务逻辑层注入RestHighLevelClient实例,然后就具备针对文档的增删改查(CRUD)能力了。RestHighLevelClient虽然是单例Bean,但不必担心线程安全问题,因为RestHighLevelClient及其内部RestClient实例均是线程安全(thread-safe)的。

代码语言:javascript
复制
@Resource
private RestHighLevelClient restHighLevelClient;

官方文档关于RestHighLevelClient中close()方法的描述 The high-level client will internally create the low-level client used to perform requests based on the provided builder. That low-level client maintains a pool of connections and starts some threads so you should close the high-level client when you are well and truly done with it and it will in turn close the internal low-level client to free those resources.


从官方描述中,我们知道RestHighLevelClient是需要关闭以释放资源的;此外,RestHighLevelClientclose()方法的内部逻辑其实就是执行RestClientclose()方法。既然我们全局维护了一个RestHighLevelClient实例,那也就是说在Spring Boot程序关停时,需要执行RestHighLevelClientclose()方法。细心的朋友可能会发现:RestHighLevelClient实现了AutoCloseable接口,即实现了close()方法,那这意味着什么呢?Bean在初始化完成后,Spring会将DisposableBeanAutoCloseableBean保存在Map中,当Spring Boot程序在优雅关停时会自动执行DisposableBeandestroy()方法和AutoCloseableclose()方法,如下图所示:

3 RestHighLevelClient Bean

在上面的整合示例中,我们直接注入了RestHighLevelClient实例。可我们并没有显式地将其声明一个Bean,仅仅引入了elasticsearch-rest-client依赖而已,那这究竟是如何实现的呢?首先,在我们服务启动类中声明了@SpringBootApplication注解,我们看一下SpringBootApplication注解接口的源码:

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
        excludeFilters = {
                @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), 
                @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
        }
)
public @interface SpringBootApplication {
}

然后,在SpringBootApplication注解接口的源码中发现了@EnableAutoConfiguration注解,打开EnableAutoConfiguration源码后发现其通过@Import注解引入了AutoConfigurationImportSelector

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

继续,我们来看一下AutoConfigurationImportSelector类的源码,selectImports()无疑是最核心的逻辑,它决定了加载哪些自动配置类。具体地,首先判断是否启用@EnableAutoConfiguration注解,如果已经启用,那么getAutoConfigurationEntry()将会从spring-boot-autoconfigure模块中META-INF目录下spring.factories文件中加载所有自动配置类。

代码语言:javascript
复制
public class AutoConfigurationImportSelector implements 
        DeferredImportSelector, 
        BeanClassLoaderAware,
        ResourceLoaderAware, 
        BeanFactoryAware, 
        EnvironmentAware, 
        Ordered {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
}

spring-factories(部分摘录)

代码语言:javascript
复制
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration

spring-factories文件中,我们看到了Elasticsearch的自动配置类入口:ElasticsearchRestClientAutoConfiguration。既然知道了自动配置的入口,距离解答我们的疑问也就很近了。从ElasticsearchRestClientAutoConfiguration源码中可以看到通过@Import注解引入了ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration

代码语言:javascript
复制
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RestClient.class)
@EnableConfigurationProperties(ElasticsearchRestClientProperties.class)
@Import({
        ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration.class,
        ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration.class,
        ElasticsearchRestClientConfigurations.RestClientFallbackConfiguration.class
})
public class ElasticsearchRestClientAutoConfiguration {
}

最后,看一下ElasticsearchRestClientConfigurations及其内部静态类RestHighLevelClientConfiguration的源码也就豁然开朗了。

代码语言:javascript
复制
class ElasticsearchRestClientConfigurations {
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(RestClientBuilder.class)
    static class RestClientBuilderConfiguration {
        @Bean
        RestClientBuilder elasticsearchRestClientBuilder(
                ElasticsearchRestClientProperties properties,
                ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
            // ······
        }
    }

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(RestHighLevelClient.class)
    static class RestHighLevelClientConfiguration {
        @Bean
        @ConditionalOnMissingBean
        RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
            return new RestHighLevelClient(restClientBuilder);
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿杜小头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Elasticsearch High Level Rest Client
    • 1 依赖引入
      • 2 使用方法
        • 2.1 配置
        • 2.2 注入RestHighLevelClient实例
      • 3 RestHighLevelClient Bean
      相关产品与服务
      Elasticsearch Service
      腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档