SpringDataElasticsearch
SpringData Elasticsearch是SpringData项目的成员之一,它基于ES的官方JavaSDK封装了一套采用Repository风格并能与Spring体系紧密集成的编程模型,包括基于注解的实体映射、Repository接口自动实现以及流畅的查询API等。这篇笔记我们以SpringBoot 3.x版本为例,简单学习一下SpringData Elasticsearch的使用。
关于ES版本绑定问题说明
ES有一个比较严重的问题是客户端SDK频繁Break Changes,从ES 6.x、7.x到现在的8.x,至今已经换了三套互不兼容的SDK,而不同版本的SpringData Elasticsearch只能集成其中某一个版本的ES客户端SDK,这也意味着如果我们使用SpringData Elasticsearch,就可能必须“自愿被绑架”到某个版本的ES上。
在SpringBoot 2.x版本中,SpringData Elasticsearch封装的是ES High Level REST Client(HLRC),这意味着仅支持ES 7.x版本,而SpringBoot 3.x版本中,SpringData Elasticsearch封装的是ES Java API Client,这意味着我们必须用ES 8.x,否则可能出现兼容性问题,如果你的实际环境不符合这一绑定关系,那么无法使用SpringData Elasticsearch!
本篇笔记使用的是SpringBoot 3.5.x,对应ES版本为8.x版本。
添加Maven依赖
使用SpringData Elasticsearch需要在pom.xml中引入如下起步依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
添加相关配置
在application.properties中,我们添加如下配置。
spring.elasticsearch.uris=http://localhost:9200
spring.elasticsearch.connection-timeout=3s
spring.elasticsearch.socket-timeout=30s
spring.elasticsearch.socket-keep-alive=true
其中,spring.elasticsearch.uris是ES服务端的地址,如果我们使用的是集群模式,这里可以使用逗号分隔配置多个地址;spring.elasticsearch.connection-timeout配置建立连接的超时时间,默认1秒,生产环境建议配置1~3秒;spring.elasticsearch.socket-timeout配置Socket数据读写超时时间,默认30秒,生产环境可根据实际业务调整;spring.elasticsearch.socket-keep-alive配置TCP层是否保活连接,默认值为false,生产环境建议配置为true以减少频繁建立连接开销。此外如果ES服务端开启了认证,还需要配置spring.elasticsearch.username和spring.elasticsearch.password。
不过只配置以上内容还不够,生产环境建议使用RestClientBuilderCustomizer根据实际情况配置连接池最大连接数、连接保活策略等。
package com.gacfox.demo.config;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticsearchConfig {
@Bean
public RestClientBuilderCustomizer customizer() {
return builder -> {
// 配置Apache HttpAsyncClient
builder.setHttpClientConfigCallback((HttpAsyncClientBuilder httpClientBuilder) -> httpClientBuilder
// 最大总连接数
.setMaxConnTotal(50)
// 每个路由(节点)的最大连接数
.setMaxConnPerRoute(10)
// 连接保活策略
.setKeepAliveStrategy((response, context) -> 60000));
};
}
}
这里可能有人会问,为什么SpringData Elasticsearch中仅暴露了少量配置,没有暴露高频使用的高级配置字段?这绝不是这些配置字段不重要,而且SpringBoot2.x时代SpringData Elasticsearch本来是有这些字段的,在SpringBoot 3.x下反而给移除了,这其实有历史原因,是Spring被ES官方的版本混乱坑怕了,ES客户端的迭代完全不遵守行业规则,客户端激进废弃完全不管下游生态,版本绑定灾难级严重,ES官方本身又不参与SpringData Elasticsearch的维护,Spring也没必要追着跑最后“热脸贴了冷屁股”,因此Spring做了彻底解绑,SpringData Elasticsearch决定只封装那些最核心、基本永远不可能改的参数,其余配置一律解耦,若有需要得自行通过代码配置,这其实可以理解为一种“防御性编程”,规避了客户端版本一变SpringData Elasticsearch直接不可用的尴尬情况。