Spring5.0:webflux中使用Elasticsearch

響應式web服務框架-webflux只需少量線程即可實現數千個併發連接。但是,與Spring-Data-MongoDB不同,Spring Data ElasticSearch本身不支持非阻塞存儲庫。
幸運的是,ElasticSearch 6的Java API可以使用RESTful接口及非阻塞HTTP客戶端實現。但是,它使用的是回調而不是類似的東西CompletableFuture。所以我們可以自己構建客戶端適配器來使在spring 5.0 使用ElasticSearch成爲可能。

Maven依賴

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
     <groupId>org.elasticsearch.client</groupId>
     <artifactId>elasticsearch-rest-high-level-client</artifactId>
     <version>6.0.1</version>
</dependency>

創建client

首先創建elasticsearch的rest客戶端對象,並注入spring

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
 
@Bean
RestHighLevelClient restHighLevelClient() {
    return new RestHighLevelClient(
            RestClient
                    .builder(new HttpHost("localhost", 9200))
                    .setRequestConfigCallback(config -> config
                            .setConnectTimeout(5_000)
                            .setConnectionRequestTimeout(5_000)
                            .setSocketTimeout(5_000)
                    )
                    .setMaxRetryTimeoutMillis(5_000));
}

執行查詢操作

調用client,傳入searchrequest 參數(User爲用戶表bean)
利用Mono包裝,輸出響應式返回(列表的話可以用Mono.flatMapMany轉爲Flux對象)

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
 
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;
 
private Mono<IndexResponse> indexDoc(User user) {
    return Mono.create(sink -> {
        IndexRequest indexRequest = new IndexRequest("people", "person", user.getUsername());
        indexRequest.source(user.getJson(), XContentType.JSON);
        client.indexAsync(indexRequest, new ActionListener<IndexResponse>() {
            @Override
            public void onResponse(IndexResponse indexResponse) {
                sink.success(indexResponse);
            }
 
            @Override
            public void onFailure(Exception e) {
                sink.error(e);
            }
        });
    });
}

參考:
Spring, Reactor and Elasticsearch: from callbacks to reactive streams
nurkiewicz博主的github項目實例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章