使用 Spring 数据 Elasticsearch(反应)连接到 ES 给出错误主机不可访问
Connecting to ES with Spring Data Elasticsearch (reactive) gives error host not reachable
我正在 运行 使用 aws-elasticsearch(带有 OpenSearch 1.1.x)服务,我正在尝试使用 spring 从 spring 应用程序连接它]-data-elasticsearch,根据 doc 我按照说明配置了 bean。
在我的本地我使用了来自我的 aws 帐户的 ssh 隧道。
我使用了这个命令:
ssh -4 -i my-creds.pem ec2-user@xxxx.xxxx.xxxx.xxxx -N -L 9200:vpc-my-custom-domain-etc.us-east-1.es.amazonaws.com:443
所以我可以通过端口 9200 在我的浏览器中通过本地主机连接 OpenSearch 仪表板。
使用来自 OpenSearch 的 OpenSearch RestHighLevelClient 和 禁用 我可以连接的 ssl,它在这里工作得很好 OS RHLC 的配置:
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
public class OSSCLientWorks{
private static final Logger log = LoggerFactory.getLogger(ClientAutoWrapper.class);
public void request(String indexName, Map<String, Object> doc) throws IOException {
//Create a client.
RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
//.addInterceptorFirst(interceptor) //-> for AwsRequestInterceptor due to some struggles i had, not necessary to work with localhost
.setSSLHostnameVerifier((hostname, session) -> true));
try (RestHighLevelClient hlClient = new RestHighLevelClient(builder)) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
var createIndexResp = hlClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
log.info("Create index resp {}", createIndexResp);
IndexRequest indexRequest = new IndexRequest(createIndexResp.index())
.id(String.valueOf(doc.get("id")))
.source(doc);
var response = hlClient.index(indexRequest, RequestOptions.DEFAULT);
var resp = response.toString();
log.info("response is {}", json);
}
}
}
,但是当我尝试使用 spring 及其反应式客户端时,我收到此错误:
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
这是我用来使用 spring-data-elasticsearch 的配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
@Configuration
@EnableReactiveElasticsearchRepositories(basePackages = {"com.elastic.repo"})
public class ElasticRestHighLevelClientConfig extends AbstractReactiveElasticsearchConfiguration {
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return ReactiveRestClients.create(clientConfiguration);
}
@Bean
public ReactiveElasticsearchOperations elasticsearchOperations(ReactiveElasticsearchClient reactiveElasticsearchClient) {
return new ReactiveElasticsearchTemplate(reactiveElasticsearchClient);
}
}
我也尝试了其他人在 SO and Github 上发布的一些解决方案,但问题仍然存在,有人对此有解决方法吗?我做错了什么?
here为了解决问题我做了个demo
非常感谢您!
编辑:清晰度
您必须使用以下usingSsl()
方法之一将 SSL 配置为对反应式客户端使用:
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.usingSsl() // <--
.build();
return ReactiveRestClients.create(clientConfiguration);
}
NoReachableHostException 只是他们在 lookupActiveHost(HostProvider 接口)失败时抛出的一般错误。
你应该调试之前发生的事情 - 对你来说它可能在这里:
@Override
public 单声道 clusterInfo() {
return createWebClient(endpoint) //
.head().uri("/") //
.exchangeToMono(it -> {
if (it.statusCode().isError()) {
state = ElasticsearchHost.offline(endpoint);
} else {
state = ElasticsearchHost.online(endpoint);
}
return Mono.just(state);
}).onErrorResume(throwable -> {
state = ElasticsearchHost.offline(endpoint);
clientProvider.getErrorListener().accept(throwable);
return Mono.just(state);
}).map(elasticsearchHost -> new ClusterInformation(Collections.singleton(elasticsearchHost)));
}
查看错误恢复的真正异常是什么。
我打赌你会遇到 SSL 握手异常,你可以在 clientConfiguration 中用 .usingSsl({SSL CONTEXT HERE}) 修复它
您可以像这样创建不安全的上下文(如果需要,转换为 java):
SSLContext.getInstance("TLS")
.apply { init(null, InsecureTrustManagerFactory.INSTANCE.trustManagers, SecureRandom()) }
我正在 运行 使用 aws-elasticsearch(带有 OpenSearch 1.1.x)服务,我正在尝试使用 spring 从 spring 应用程序连接它]-data-elasticsearch,根据 doc 我按照说明配置了 bean。
在我的本地我使用了来自我的 aws 帐户的 ssh 隧道。
我使用了这个命令:
ssh -4 -i my-creds.pem ec2-user@xxxx.xxxx.xxxx.xxxx -N -L 9200:vpc-my-custom-domain-etc.us-east-1.es.amazonaws.com:443
所以我可以通过端口 9200 在我的浏览器中通过本地主机连接 OpenSearch 仪表板。
使用来自 OpenSearch 的 OpenSearch RestHighLevelClient 和 禁用 我可以连接的 ssl,它在这里工作得很好 OS RHLC 的配置:
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
public class OSSCLientWorks{
private static final Logger log = LoggerFactory.getLogger(ClientAutoWrapper.class);
public void request(String indexName, Map<String, Object> doc) throws IOException {
//Create a client.
RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
//.addInterceptorFirst(interceptor) //-> for AwsRequestInterceptor due to some struggles i had, not necessary to work with localhost
.setSSLHostnameVerifier((hostname, session) -> true));
try (RestHighLevelClient hlClient = new RestHighLevelClient(builder)) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
var createIndexResp = hlClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
log.info("Create index resp {}", createIndexResp);
IndexRequest indexRequest = new IndexRequest(createIndexResp.index())
.id(String.valueOf(doc.get("id")))
.source(doc);
var response = hlClient.index(indexRequest, RequestOptions.DEFAULT);
var resp = response.toString();
log.info("response is {}", json);
}
}
}
,但是当我尝试使用 spring 及其反应式客户端时,我收到此错误:
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
这是我用来使用 spring-data-elasticsearch 的配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
@Configuration
@EnableReactiveElasticsearchRepositories(basePackages = {"com.elastic.repo"})
public class ElasticRestHighLevelClientConfig extends AbstractReactiveElasticsearchConfiguration {
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return ReactiveRestClients.create(clientConfiguration);
}
@Bean
public ReactiveElasticsearchOperations elasticsearchOperations(ReactiveElasticsearchClient reactiveElasticsearchClient) {
return new ReactiveElasticsearchTemplate(reactiveElasticsearchClient);
}
}
我也尝试了其他人在 SO and Github 上发布的一些解决方案,但问题仍然存在,有人对此有解决方法吗?我做错了什么?
here为了解决问题我做了个demo
非常感谢您!
编辑:清晰度
您必须使用以下usingSsl()
方法之一将 SSL 配置为对反应式客户端使用:
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.usingSsl() // <--
.build();
return ReactiveRestClients.create(clientConfiguration);
}
NoReachableHostException 只是他们在 lookupActiveHost(HostProvider 接口)失败时抛出的一般错误。
你应该调试之前发生的事情 - 对你来说它可能在这里:
@Override public 单声道 clusterInfo() {
return createWebClient(endpoint) //
.head().uri("/") //
.exchangeToMono(it -> {
if (it.statusCode().isError()) {
state = ElasticsearchHost.offline(endpoint);
} else {
state = ElasticsearchHost.online(endpoint);
}
return Mono.just(state);
}).onErrorResume(throwable -> {
state = ElasticsearchHost.offline(endpoint);
clientProvider.getErrorListener().accept(throwable);
return Mono.just(state);
}).map(elasticsearchHost -> new ClusterInformation(Collections.singleton(elasticsearchHost)));
}
查看错误恢复的真正异常是什么。
我打赌你会遇到 SSL 握手异常,你可以在 clientConfiguration 中用 .usingSsl({SSL CONTEXT HERE}) 修复它
您可以像这样创建不安全的上下文(如果需要,转换为 java):
SSLContext.getInstance("TLS") .apply { init(null, InsecureTrustManagerFactory.INSTANCE.trustManagers, SecureRandom()) }