Spring 数据 Elasticsearch:以编程方式重新初始化 elasticsearch hosts/cluster_password
Spring data Elasticsearch : Reinitialise elasticsearch hosts/cluster_password programmatically
TL;DR:如何使用 spring-data-elasticsearch 在运行时切换弹性搜索主机?
我们有一个 spring 启动应用程序 (v: 2.5.2) 使用 spring data elasticsearch (v: 4.2.2)。
我正在使用 java 配置来初始化 ES 连接,如 spring 文档的 High Level Rest Client 部分所述。
我们有一个要求,我们需要在运行时更改 elasticsearch 主机,而不是手动重启我们的服务器。
我尝试使用类似于 spring 执行器的 RestartEndpoint 在主机名配置更改时重新启动 spring IOC。但这似乎只适用于 spring 的嵌入式 tomcat 而不是我们使用的外部 tomcat。
有其他方法吗?
[万一发生灾难,我们需要切换到备份]
开箱即用。
一个想法(我没有尝试过):您需要创建自己的 ElasticsearchOperations
接口实现,让我们将其称为 MyOperations
和 return 来自您的配置继承的 AbstractElasticsearchConfiguration#elasticsearchOperations()
方法。在这个 MyOperations
实现(这是一个单例 Spring bean)中,您将创建一个委托 ElasticsearchOperations
,其代码与连接到正常的配置 class 中的代码相同簇。然后,您实现中的每个方法都会委托给委托的相应方法。
在失败的情况下,您的实现将创建一个新的委托,现在连接到辅助集群并用它替换第一个。或者创建两者并实现切换功能以在两者之间切换。
扩展 P.J.Meisch、
提供的答案
为 ElasticsearchOperations
创建自定义实现
public class CustomElasticsearchOperations implements ElasticsearchOperations {
private ElasticsearchOperations delegateElasticSearchOp;
/**
* Main Constructor to create the instance using existing elasticsearchConverter bean
* @param elasticsearchConverter : ElasticsearchConverter
*/
public CustomElasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
updateElasticsearchOperationDelegate(elasticsearchConverter);
}
private ElasticsearchOperations createNewElasticsearchOperationDelegate(ElasticsearchConverter elasticsearchConverter){
return new ElasticsearchRestTemplate(ElasticsearchRestHighLevelClientProvider.INSTANCE.elasticsearchClient(),elasticsearchConverter);
}
/**
* Method to update the delegate ElasticsearchRestTemplate to register elasticsearch configurations
* @param elasticsearchConverter : Default spring lib provided ElasticsearchConverter instance
*/
public void updateElasticsearchOperationDelegate(ElasticsearchConverter elasticsearchConverter){
this.delegateElasticSearchOp = createNewElasticsearchOperationDelegate(elasticsearchConverter);
}
/*
* ElasticsearchOperations method implementation using Delegate ElasticsearchRestTemplatea
*/
@Override
public IndexOperations indexOps(Class<?> aClass) {
return delegateElasticSearchOp.indexOps(aClass);
}
@Override
public IndexOperations indexOps(IndexCoordinates indexCoordinates) {
return delegateElasticSearchOp.indexOps(indexCoordinates);
}
@Override
public ClusterOperations cluster() {
return delegateElasticSearchOp.cluster();
}
@Override
public ElasticsearchConverter getElasticsearchConverter() {
return delegateElasticSearchOp.getElasticsearchConverter();
}
// And so on... delegate the impl of overriden method to existing ElasticsearchRestTemplate
}
其中 ElasticsearchRestHighLevelClientProvider
是一个 class,它包含创建对象的逻辑 RestHighLevelClient
,它包含当前集群配置的值
// This is a sample from spring documentation. Create your own rest client with your own configs
public enum ElasticsearchRestHighLevelClientProvider{
INSTANCE;
// below is a sample, change it according to your requirements.
public RestHighLevelClient elasticsearchClient() {
String hosts [] = getLatestConfigs().getHosts();
final ClientConfiguration clientConfiguration =
ClientConfiguration.builder()
.connectedTo(hosts)
.build();
return RestClients.create(clientConfiguration).rest();
}
// your code for fetching cluster configs..
}
最后,注册CustomElasticsearchOperations
的bean
@Configuration
public class ElasticSearchAutoConfigurations extends ElasticsearchConfigurationSupport {
@Bean(
name = {"elasticsearchOperations", "elasticsearchTemplate"}
)
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
return new CustomElasticsearchOperations(elasticsearchConverter);
}
}
现在,当您的配置更改时,您可以自动装配 ElasticsearchOperations
和 ElasticsearchConverter
beans 的实例,并调用 ElasticsearchOperations#updateElasticsearchOperationDelegate(elasticsearchConverter)
这将用新配置替换 CustomElasticsearchOperations
单例 bean 中 ElasticsearchRestTemplate
的实例,新请求将转到您要切换到的集群。
注意
如果您已自动装配 ElasticsearchRestTemplate
以对 elasticsearch 进行非 spring 基于存储库的调用,请将自动装配的候选者更改为父接口 ElasticsearchOperations
为 ElasticsearchRestTemplate
的实例将不会出现在应用程序上下文中
ElasticsearchConverter
已在 ElasticsearchConfigurationSupport
class 中创建。所以不需要再创建这个bean
TL;DR:如何使用 spring-data-elasticsearch 在运行时切换弹性搜索主机?
我们有一个 spring 启动应用程序 (v: 2.5.2) 使用 spring data elasticsearch (v: 4.2.2)。
我正在使用 java 配置来初始化 ES 连接,如 spring 文档的 High Level Rest Client 部分所述。
我们有一个要求,我们需要在运行时更改 elasticsearch 主机,而不是手动重启我们的服务器。
我尝试使用类似于 spring 执行器的 RestartEndpoint 在主机名配置更改时重新启动 spring IOC。但这似乎只适用于 spring 的嵌入式 tomcat 而不是我们使用的外部 tomcat。
有其他方法吗?
[万一发生灾难,我们需要切换到备份]
开箱即用。
一个想法(我没有尝试过):您需要创建自己的 ElasticsearchOperations
接口实现,让我们将其称为 MyOperations
和 return 来自您的配置继承的 AbstractElasticsearchConfiguration#elasticsearchOperations()
方法。在这个 MyOperations
实现(这是一个单例 Spring bean)中,您将创建一个委托 ElasticsearchOperations
,其代码与连接到正常的配置 class 中的代码相同簇。然后,您实现中的每个方法都会委托给委托的相应方法。
在失败的情况下,您的实现将创建一个新的委托,现在连接到辅助集群并用它替换第一个。或者创建两者并实现切换功能以在两者之间切换。
扩展 P.J.Meisch、
提供的答案为 ElasticsearchOperations
public class CustomElasticsearchOperations implements ElasticsearchOperations {
private ElasticsearchOperations delegateElasticSearchOp;
/**
* Main Constructor to create the instance using existing elasticsearchConverter bean
* @param elasticsearchConverter : ElasticsearchConverter
*/
public CustomElasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
updateElasticsearchOperationDelegate(elasticsearchConverter);
}
private ElasticsearchOperations createNewElasticsearchOperationDelegate(ElasticsearchConverter elasticsearchConverter){
return new ElasticsearchRestTemplate(ElasticsearchRestHighLevelClientProvider.INSTANCE.elasticsearchClient(),elasticsearchConverter);
}
/**
* Method to update the delegate ElasticsearchRestTemplate to register elasticsearch configurations
* @param elasticsearchConverter : Default spring lib provided ElasticsearchConverter instance
*/
public void updateElasticsearchOperationDelegate(ElasticsearchConverter elasticsearchConverter){
this.delegateElasticSearchOp = createNewElasticsearchOperationDelegate(elasticsearchConverter);
}
/*
* ElasticsearchOperations method implementation using Delegate ElasticsearchRestTemplatea
*/
@Override
public IndexOperations indexOps(Class<?> aClass) {
return delegateElasticSearchOp.indexOps(aClass);
}
@Override
public IndexOperations indexOps(IndexCoordinates indexCoordinates) {
return delegateElasticSearchOp.indexOps(indexCoordinates);
}
@Override
public ClusterOperations cluster() {
return delegateElasticSearchOp.cluster();
}
@Override
public ElasticsearchConverter getElasticsearchConverter() {
return delegateElasticSearchOp.getElasticsearchConverter();
}
// And so on... delegate the impl of overriden method to existing ElasticsearchRestTemplate
}
其中 ElasticsearchRestHighLevelClientProvider
是一个 class,它包含创建对象的逻辑 RestHighLevelClient
,它包含当前集群配置的值
// This is a sample from spring documentation. Create your own rest client with your own configs
public enum ElasticsearchRestHighLevelClientProvider{
INSTANCE;
// below is a sample, change it according to your requirements.
public RestHighLevelClient elasticsearchClient() {
String hosts [] = getLatestConfigs().getHosts();
final ClientConfiguration clientConfiguration =
ClientConfiguration.builder()
.connectedTo(hosts)
.build();
return RestClients.create(clientConfiguration).rest();
}
// your code for fetching cluster configs..
}
最后,注册CustomElasticsearchOperations
@Configuration
public class ElasticSearchAutoConfigurations extends ElasticsearchConfigurationSupport {
@Bean(
name = {"elasticsearchOperations", "elasticsearchTemplate"}
)
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
return new CustomElasticsearchOperations(elasticsearchConverter);
}
}
现在,当您的配置更改时,您可以自动装配 ElasticsearchOperations
和 ElasticsearchConverter
beans 的实例,并调用 ElasticsearchOperations#updateElasticsearchOperationDelegate(elasticsearchConverter)
这将用新配置替换 CustomElasticsearchOperations
单例 bean 中 ElasticsearchRestTemplate
的实例,新请求将转到您要切换到的集群。
注意
如果您已自动装配
ElasticsearchRestTemplate
以对 elasticsearch 进行非 spring 基于存储库的调用,请将自动装配的候选者更改为父接口ElasticsearchOperations
为ElasticsearchRestTemplate
的实例将不会出现在应用程序上下文中ElasticsearchConverter
已在ElasticsearchConfigurationSupport
class 中创建。所以不需要再创建这个bean