2020年八月修訂:
SpringBoot 已經(jīng)升級了ES的客戶端阁最,Spring Data Elasticsearch 4.0已經(jīng)使用 Elasticsearch 7.6.2了,若希望使用Spring的ES模板可已自行嘗試.
首先明確一點搭独,SpringBoot自帶的ES模板,不建議使用荸频,建議使用Rest Client留晚。如果業(yè)務(wù)簡單,且無特殊要求毙死,可以使用SpringBoot的模板ElasticsearchRepository來搞定燎潮。這個非常簡單,這里不作介紹扼倘,有需要看最底下的連接
ElasticsearchRepository
- 優(yōu)點: 簡單确封,SpringBoot無縫對接,配置簡單
- 缺點: 基于即將廢棄的TransportClient再菊, 不能支持復(fù)雜的業(yè)務(wù)
創(chuàng)建SpringBoot項目
如果不會創(chuàng)建爪喘,可以參考:http://www.reibang.com/p/2101d176555b
maven 和 gradle都可以,建議使用 JDK使用1.8 因為Elasticsearch 的Java High Level REST Client 對java的版本要求是8纠拔。你們可以去官網(wǎng)查證秉剑。
【參考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-maven.html】
添加Rest Client依賴,增加配置
maven工程:
<!-- 工具類 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<!-- Java Low Level REST Client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.3.2</version>
</dependency>
<!-- Java High Level REST Client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.3.2</version>
</dependency>
gradle 工程
dependencies {
compile 'org.elasticsearch.client:elasticsearch-rest-client:6.3.2'
compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.3.2'
}
版本號請根據(jù)自己安裝的ES版本酌情選擇稠诲,因為ES5和ES6的API有些差別
編寫單例Rest Low Level Client 和Rest High Level Client的bean
想用Spring 的IOC管理ES的連接客戶端侦鹏,可分下面幾步
- 配置ES節(jié)點
- 配置Rest Client
- 配置Rest High Level Client
- 使用IOC注入
根據(jù)我從其他網(wǎng)站上查詢的資料诡曙,Rest Client是長連接,而且內(nèi)部有默認(rèn)的線程池管理略水,因此一般無需自定義線程池管理連接价卤。如果不對請指正
基于以上結(jié)論。先把連接點全部配置到配置文件中.(為了省事渊涝,直接一個數(shù)組搞定慎璧,有心的朋友可以注入成list+對象)
- 配置節(jié)點
elasticsearch.ip=127.0.0.1:9200,127.0.0.2:9200,127.0.0.3:9200,127.0.0.4:9200,127.0.0.5:9200,127.0.0.6:9200
- 編寫Config類,配置Rest Client和Rest High Level Client
請找一個pack跨释,創(chuàng)建ElasticsearchRestClient 類
/**
* this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
* Create By @author zing @date 2018/7/18 17:20
*/
@Slf4j
@Configuration
public class ElasticsearchRestClient {
private static final int ADDRESS_LENGTH = 2;
private static final String HTTP_SCHEME = "http";
/**
* 使用冒號隔開ip和端口1
*/
@Value("${elasticsearch.ip}")
String[] ipAddress;
@Bean
public RestClientBuilder restClientBuilder() {
HttpHost[] hosts = Arrays.stream(ipAddress)
.map(this::makeHttpHost)
.filter(Objects::nonNull)
.toArray(HttpHost[]::new);
log.debug("hosts:{}", Arrays.toString(hosts));
return RestClient.builder(hosts);
}
@Bean(name = "highLevelClient")
public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
restClientBuilder.setMaxRetryTimeoutMillis(60000);
return new RestHighLevelClient(restClientBuilder);
}
private HttpHost makeHttpHost(String s) {
assert StringUtils.isNotEmpty(s);
String[] address = s.split(":");
if (address.length == ADDRESS_LENGTH) {
String ip = address[0];
int port = Integer.parseInt(address[1]);
return new HttpHost(ip, port, HTTP_SCHEME);
} else {
return null;
}
}
}
注:@Slf4j注解是lombok的日志注解胸私,可以自行刪除,切換成其他日志方式鳖谈;Stream不會的朋友可以寫成for循環(huán)岁疼,速度大約能快些
業(yè)務(wù)使用
強烈建議從TransportClient遷移到RestClient,因為業(yè)務(wù)壓測發(fā)現(xiàn)TransportClient存在并發(fā)瓶頸蚯姆。
在service里然后使用之前創(chuàng)建的highLevelClient呢五续?
demo如下
@Service
public class XXXServiceImpl implements XXXService {
@Autowired
RestHighLevelClient highLevelClient;
@Override
public boolean testEsRestClient(){
SearchRequest searchRequest = new SearchRequest("gdp_tops*");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("city", "北京市"));
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
try {
SearchResponse response = highLevelClient.search(searchRequest);
Arrays.stream(response.getHits().getHits())
.forEach(i -> {
System.out.println(i.getIndex());
System.out.println(i.getSource());
System.out.println(i.getType());
});
System.out.println(response.getHits().totalHits);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
如果你沒有Query DSL的基礎(chǔ),建議先學(xué)習(xí)ES的基本查詢方法龄恋,如果有時間我可能會寫一些疙驾,但是網(wǎng)上已經(jīng)有N多入門教程。
ps:
ES 沒有事務(wù)概念郭毕,ES存儲暫時可以理解成每次請求是原子性的它碎,如果涉及多種數(shù)據(jù)庫操作,如:存完ES再存MySQL显押,且要保證一致性的話扳肛,可以考慮使用消息隊列做失敗補償,如果需要及時返回的存儲乘碑,最好不要同時操作兩種數(shù)據(jù)庫挖息。否則則需要手動控制事務(wù)失敗后的恢復(fù)。相對麻煩很多
RestClient其他詳細(xì)使用方法參考我前面的文章:
Elasticsearch Java Rest Client 上手指南(上)
Elasticsearch Java Rest Client 上手指南(下)
想用自帶SpringBoot光環(huán)的ElasticsearchRepository的可參考:https://juejin.im/post/5aec0b386fb9a07abb23784d
By: Max Zing
轉(zhuǎn)載請注明出處:http://www.reibang.com/p/0b4f5e41405e
如有錯誤兽肤,請不吝指正套腹。謝謝
我的博客:https://micorochio.github.io/
轉(zhuǎn)載請勿使用本文章推廣任何自媒體!請勿追加任何媒體的二維碼资铡!
一口奶到位电禀,我把項目里的代碼抽離做成了Maven版的Sample,https://github.com/xzing/SpringBootElasticsearchSample.git
各位看官喜歡可以點個贊
====
感謝@一納秒的指正笤休,由于項目繁忙尖飞,忘記更新博客的代碼了,文章不是一天寫完的,所以有錯誤的話歡迎指正