Elastic專(zhuān)欄目錄
第一章 SpringBoot集成ElasticSearch(2023-01-28)
前言
例如:業(yè)務(wù)中需要使用es,所以做一些客戶(hù)端選型,熟悉一下基本的操作,所以記錄這篇博客,有關(guān)概念理論性的文章還在整理過(guò)程中,后續(xù)會(huì)整理個(gè)系列
參考文章
Spring認(rèn)證中國(guó)教育管理中心-Spring Data Elasticsearch教程一
SpringData集成Elasticsearch
Spring Data ElasticSearch簡(jiǎn)介
SpringBoot整合ES的三種方式(API、REST Client、Data-ES)
(一)springboot集成ES
02-Elasticsearch-集群概念入門(mén)
springboot項(xiàng)目使用ES
Elasticsearch【快速入門(mén)】
第一節(jié)參考
:
干貨 | Elasticsearch Java 客戶(hù)端演進(jìn)歷史和選型指南
第二節(jié)參考
:
基于spring-boot使用elasticsearch Java API 客戶(hù)端
Elasticsearch8.x版本中RestHighLevelClient被棄用,新版本中全新的Java客戶(hù)端Elasticsearch Java API Client中常用API練習(xí)
Elasticsearch RestHighLevelClient 已標(biāo)記為被棄用 它的替代方案 Elasticsearch Java API Client 的基礎(chǔ)教程及遷移方案
第三節(jié)參考:
ES客戶(hù)端(RestHighLevelClient、SpringDataElasticsearch 框架)使用指南
一、Elasticsearch客戶(hù)端現(xiàn)狀
說(shuō)實(shí)話,在es的java客戶(hù)端這方面es官方就突出兩個(gè)字:坑爹
RestHighLevelClient在7.15之后的版本已被標(biāo)記為棄用狀態(tài),8.0新版本將不再支持,而將Elasticsearch Java API Client作為新的推薦客戶(hù)端
es官方文檔說(shuō)明
SpringDataElasticsearch(4.0.0.RELEASE)使用的客戶(hù)端為RestHighLevelClient
Spring官方對(duì)于es默認(rèn)客戶(hù)端變動(dòng)的一些說(shuō)明:
https://github.com/spring-projects/spring-data-elasticsearch/tree/5.0.x
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
選型關(guān)注要點(diǎn):
Elasticsearch 集群的版本。
歷史版本的兼容性問(wèn)題。
未來(lái)升級(jí)版本、擴(kuò)展性問(wèn)題。
所選型的客戶(hù)端是否更新及時(shí),能適配將來(lái)的版本。
如果當(dāng)前是:7.X 版本且不考慮升級(jí),那就 High Level REST 客戶(hù)端。
如果當(dāng)前是:8.X 版本,那就 Elasticsearch Java API 客戶(hù)端。
如果當(dāng)前是:5.X、6.X 版本,推薦盡早升級(jí)集群版本。
JEST 已不更新和維護(hù),不推薦使用。
BBoss 客戶(hù)端,根據(jù)自己業(yè)務(wù)需要做選型。
Spring 框架的 Web 項(xiàng)目,可以使用 Spring Data Elasticsearch,但關(guān)注它的更新版本,截止:2022-06-17,支持到:7.17.3 版本
spring官方說(shuō)明在springboot3版本才會(huì)支持新客戶(hù)端,之前還是使用RestHighLevelClient,而springboot3基于spring6和jdk17,這就讓人很難受了,自己玩玩用什么jdk都無(wú)所謂,但如果業(yè)務(wù)上就行不通了,所以以下展示如何不使用SpringDataElasticsearch接入最新的Elasticsearch Java API Client
二、SpringBoot集成ElasticSearch(Elasticsearch Java API Client)
1.Java API Client介紹
maven中央倉(cāng)庫(kù)中的elasticsearch-java相關(guān)版本
從7.15.0版本(beta版本)開(kāi)始,截至2023-01-28最新版本為8.6.1
官方文檔介紹,7.16版本
https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/7.16/introduction.html
重點(diǎn)是強(qiáng)類(lèi)型
特性
強(qiáng)類(lèi)型
提供阻塞和異步的客戶(hù)端
Java API Client使用建造者模式和函數(shù)模式
新版本主要變動(dòng)
兼容性
2.引入庫(kù)
直接使用7的最后一個(gè)版本
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>7.17.8</version>
</dependency>
3.1 配置客戶(hù)端(無(wú)密碼)
代碼如下(示例):
@Configuration
public class JavaApiClientConfiguration {
@Value("${es.hosts.name}")
private String hosts;
/**
* 解析配置的字符串,轉(zhuǎn)為HttpHost對(duì)象數(shù)組, hosts example: 127.0.0.1:9200,127.0.0.1:9300
*
* @return
*/
private HttpHost[] toHttpHost() {
if (StringUtils.isEmpty(hosts)) {
throw new RuntimeException("invalid elasticsearch configuration");
}
String[] hostArray = hosts.split(",");
HttpHost[] httpHosts = new HttpHost[hostArray.length];
HttpHost httpHost;
for (int i = 0; i < hostArray.length; i++) {
String[] strings = hostArray[i].split(":");
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
httpHosts[i] = httpHost;
}
return httpHosts;
}
@Bean
public ElasticsearchClient elasticsearchClient() {
HttpHost[] httpHosts = toHttpHost();
RestClient restClient = RestClient.builder(httpHosts).build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
@Bean
public ElasticsearchAsyncClient elasticsearchAsyncClient() {
HttpHost[] httpHosts = toHttpHost();
RestClient restClient = RestClient.builder(httpHosts).build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchAsyncClient(transport);
}
}
3.2 配置客戶(hù)端(有密碼)
@Configuration
public class EsClientConfig {
@Value("${spring.elasticsearch.uris}")
private String hosts;
@Value("${spring.elasticsearch.username}")
private String username;
@Value("${spring.elasticsearch.password}")
private String password;
/**
* 解析配置的字符串,轉(zhuǎn)為HttpHost對(duì)象數(shù)組, hosts example: 127.0.0.1:9200,127.0.0.1:9300
*
* @return
*/
private HttpHost[] toHttpHost() {
if (StringUtils.isEmpty(hosts)) {
throw new RuntimeException("invalid elasticsearch configuration");
}
String[] hostArray = hosts.split(",");
HttpHost[] httpHosts = new HttpHost[hostArray.length];
HttpHost httpHost;
for (int i = 0; i < hostArray.length; i++) {
String[] strings = hostArray[i].split(":");
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
httpHosts[i] = httpHost;
}
return httpHosts;
}
@Bean
public ElasticsearchClient elasticsearchClient() {
HttpHost[] httpHosts = toHttpHost();
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClient restClient = RestClient.builder(httpHosts).setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
@Bean
public ElasticsearchAsyncClient elasticsearchAsyncClient() {
HttpHost[] httpHosts = toHttpHost();
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClient restClient = RestClient.builder(httpHosts).setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchAsyncClient(transport);
}
}
4. 啟動(dòng)異常
由于使用的es服務(wù)器版本為7.6.2,使用的 Java API Client版本為7.17.8(7的最后一個(gè)版本),版本不一致,所以出現(xiàn)了一些異常需要處理,如果一致,可直接跳過(guò)本節(jié),本節(jié)純屬瞎折騰。
4.1兼容性請(qǐng)求頭compatible-with=7
解決辦法
如何在 Elasticsearch Java API 客戶(hù)端中禁用兼容性標(biāo)頭?
es服務(wù)端是舊版本,而這個(gè)請(qǐng)求頭是給8版本的es服務(wù)端使用,用以兼容7客戶(hù)端的請(qǐng)求,所以需要覆蓋這個(gè)請(qǐng)求頭
3.1的客戶(hù)端配置代碼修改elasticsearchclient的構(gòu)造方法
@Bean
public ElasticsearchClient elasticsearchClient() {
HttpHost[] httpHosts = toHttpHost();
RestClient restClient = RestClient
.builder(httpHosts)
.setDefaultHeaders(new Header[]{
new BasicHeader("Content-Type", "application/json; charset=UTF-8")})
.build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/api-conventions.html
4.2缺失響應(yīng)頭X-Elastic-Product(Elasticsearch)
co.elastic.clients.transport.TransportException: [es/search] Missing [X-Elastic-Product] header
新版本的服務(wù)端es會(huì)響應(yīng)這個(gè)header,但由于是舊版本,所以未響應(yīng),而客戶(hù)端使用的新版本會(huì)檢查這個(gè)響應(yīng)頭,所以會(huì)報(bào)錯(cuò),但服務(wù)端已經(jīng)正常執(zhí)行
客戶(hù)端代碼中會(huì)單獨(dú)檢查數(shù)據(jù)庫(kù)屬于 Elastic 還是分叉產(chǎn)物。更新說(shuō)明中提到,“如果響應(yīng)當(dāng)中沒(méi)有 X-Elastic-Product HTTP 標(biāo)頭,或者 X-Elastic-Product HTTP 標(biāo)頭的值不是 Elasticsearch,就會(huì)引發(fā)錯(cuò)誤。
之所以加入此請(qǐng)求頭的原因是elastic官方和aws的爭(zhēng)端,如要詳細(xì)了解淵源,請(qǐng)查看此篇博客
換協(xié)議、改代碼,Elastic 要逼開(kāi)發(fā)者二選一?
官方鏈接文檔:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/release-notes-7.14.0.html
https://github.com/elastic/elasticsearch/issues/73424
https://github.com/elastic/elasticsearch/issues/73434
解決辦法
新建配置類(lèi)
@Component
public class ResponseInterceptor implements RestClientBuilder.HttpClientConfigCallback {
/**
* Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the {@link RestClient}.
* Commonly used to customize the default {@link CredentialsProvider} for authentication
* or the {@link SchemeIOSessionStrategy} for communication through ssl without losing any other useful default
* value that the {@link RestClientBuilder} internally sets, like connection pooling.
*
* @param httpClientBuilder
*/
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
HttpResponseInterceptor httpResponseInterceptor = new HttpResponseInterceptor() {
/**
* Processes a response.
* On the server side, this step is performed before the response is
* sent to the client. On the client side, this step is performed
* on incoming messages before the message body is evaluated.
*
* @param response the response to postprocess
* @param context the context for the request
* @throws HttpException in case of an HTTP protocol violation
* @throws IOException in case of an I/O error
*/
@Override
public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
response.addHeader("X-Elastic-Product", "Elasticsearch");
}
};
httpClientBuilder.addInterceptorFirst(httpResponseInterceptor);
return httpClientBuilder;
}
}
3.1配置類(lèi)中注入攔截器
@Autowired
private ResponseInterceptor responseInterceptor;
修改elasticsearchclient的構(gòu)造方法文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-467231.html
@Bean
public ElasticsearchClient elasticsearchClient() {
HttpHost[] httpHosts = toHttpHost();
RestClient restClient = RestClient
.builder(httpHosts)
.setDefaultHeaders(new Header[]{
new BasicHeader("Content-Type", "application/json; charset=UTF-8")})
.setHttpClientConfigCallback(responseInterceptor)
.build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
5.基本使用
@RestController
public class JavaApiClientService {
@Autowired
private ElasticsearchClient client;
public void createIndex() {
try {
client.indices().create(builder -> {
builder.index("animal")
.settings(s -> s.numberOfShards("3").numberOfReplicas("0"));
return builder;
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void deleteIndex() throws IOException {
client.indices().delete(builder -> {
builder.index("animal");
return builder;
});
}
public void addDocument() throws IOException {
client.index(builder -> {
builder.index("animal").document(new Animal()).id("0");
return builder;
});
}
public void deleteDocument() throws IOException {
client.delete(builder -> {
builder.index("animal").id("0");
return builder;
});
}
}
三、SpringBoot集成SpringDataElasticsearch
雖然舊版本的客戶(hù)端會(huì)逐步廢棄,但估計(jì)是個(gè)較長(zhǎng)的過(guò)程,當(dāng)前使用的es服務(wù)器主流版本仍舊為7,所以也需要熟悉SpringDataElasticsearch,RestHighLevelClient的使用1. 引入庫(kù)
2.1 配置客戶(hù)端
3. 基本使用
總結(jié)
例如:以上就是今天要講的內(nèi)容,本文僅僅簡(jiǎn)單介紹了pandas的使用,而pandas提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-467231.html
到了這里,關(guān)于SpringBoot集成Elasticsearch客戶(hù)端(新舊版本)(2023-01-28)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!