SpringBoot整合Elasticsearch的Java Rest Client

2020年八月修訂:
SpringBoot 已經(jīng)升級(jí)了ES的客戶端,Spring Data Elasticsearch 4.0已經(jīng)使用 Elasticsearch 7.6.2了,若希望使用Spring的ES模板可已自行嘗試.


首先明確一點(diǎn),SpringBoot自帶的ES模板,不建議使用,建議使用Rest Client。如果業(yè)務(wù)簡單,且無特殊要求,可以使用SpringBoot的模板ElasticsearchRepository來搞定。這個(gè)非常簡單,這里不作介紹,有需要看最底下的連接

ElasticsearchRepository

  • 優(yōu)點(diǎn): 簡單,SpringBoot無縫對(duì)接,配置簡單
  • 缺點(diǎn): 基于即將廢棄的TransportClient, 不能支持復(fù)雜的業(yè)務(wù)

創(chuàng)建SpringBoot項(xiàng)目

IDEA 創(chuàng)建SpringBoot工程

如果不會(huì)創(chuàng)建,可以參考:http://www.lxweimin.com/p/2101d176555b
maven 和 gradle都可以,建議使用 JDK使用1.8 因?yàn)镋lasticsearch 的Java High Level REST Client 對(duì)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'
}

版本號(hào)請(qǐng)根據(jù)自己安裝的ES版本酌情選擇,因?yàn)镋S5和ES6的API有些差別

編寫單例Rest Low Level Client 和Rest High Level Client的bean

想用Spring 的IOC管理ES的連接客戶端,可分下面幾步

  • 配置ES節(jié)點(diǎn)
  • 配置Rest Client
  • 配置Rest High Level Client
  • 使用IOC注入

根據(jù)我從其他網(wǎng)站上查詢的資料,Rest Client是長連接,而且內(nèi)部有默認(rèn)的線程池管理,因此一般無需自定義線程池管理連接。如果不對(duì)請(qǐng)指正

基于以上結(jié)論。先把連接點(diǎn)全部配置到配置文件中.(為了省事,直接一個(gè)數(shù)組搞定,有心的朋友可以注入成list+對(duì)象)

  1. 配置節(jié)點(diǎn)
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
  1. 編寫Config類,配置Rest Client和Rest High Level Client

請(qǐng)找一個(gè)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";

    /**
     * 使用冒號(hào)隔開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不會(huì)的朋友可以寫成for循環(huán),速度大約能快些

業(yè)務(wù)使用

強(qiáng)烈建議從TransportClient遷移到RestClient,因?yàn)闃I(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的基本查詢方法,如果有時(shí)間我可能會(huì)寫一些,但是網(wǎng)上已經(jīng)有N多入門教程。

ps:

ES 沒有事務(wù)概念,ES存儲(chǔ)暫時(shí)可以理解成每次請(qǐng)求是原子性的,如果涉及多種數(shù)據(jù)庫操作,如:存完ES再存MySQL,且要保證一致性的話,可以考慮使用消息隊(duì)列做失敗補(bǔ)償,如果需要及時(shí)返回的存儲(chǔ),最好不要同時(shí)操作兩種數(shù)據(jù)庫。否則則需要手動(dòng)控制事務(wù)失敗后的恢復(fù)。相對(duì)麻煩很多

RestClient其他詳細(xì)使用方法參考我前面的文章:

Elasticsearch Java Rest Client 上手指南(上)

Elasticsearch Java Rest Client 上手指南(下)

想用自帶SpringBoot光環(huán)的ElasticsearchRepository的可參考:https://juejin.im/post/5aec0b386fb9a07abb23784d

By: Max Zing
轉(zhuǎn)載請(qǐng)注明出處:http://www.lxweimin.com/p/0b4f5e41405e
如有錯(cuò)誤,請(qǐng)不吝指正。謝謝
我的博客:https://micorochio.github.io/

轉(zhuǎn)載請(qǐng)勿使用本文章推廣任何自媒體!請(qǐng)勿追加任何媒體的二維碼!

一口奶到位,我把項(xiàng)目里的代碼抽離做成了Maven版的Sample,https://github.com/xzing/SpringBootElasticsearchSample.git
各位看官喜歡可以點(diǎn)個(gè)贊

====
感謝@一納秒的指正,由于項(xiàng)目繁忙,忘記更新博客的代碼了,文章不是一天寫完的,所以有錯(cuò)誤的話歡迎指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容

  • 說明 在明確了ES的基本概念和使用方法后,我們來學(xué)習(xí)如何使用ES的Java API.本文假設(shè)你已經(jīng)對(duì)ES的基本概念...
    epicGeek閱讀 43,629評(píng)論 4 44
  • 開始看Elasticsearch Java API 的時(shí)候,被這段話澆了盆涼水 We plan on deprec...
    MaxZing閱讀 41,494評(píng)論 9 19
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,779評(píng)論 18 139
  • 1. 安裝: 要求至少Java 8(推薦使用Oracle JDK version 1.8.0_121)并設(shè)置$JA...
    simonsgj閱讀 2,271評(píng)論 0 9
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,887評(píng)論 6 342