響應式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項目實例