响应式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项目实例