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);
    }
}

现在,当您的配置更改时,您可以自动装配 ElasticsearchOperationsElasticsearchConverter beans 的实例,并调用 ElasticsearchOperations#updateElasticsearchOperationDelegate(elasticsearchConverter)

这将用新配置替换 CustomElasticsearchOperations 单例 bean 中 ElasticsearchRestTemplate 的实例,新请求将转到您要切换到的集群。

注意

  • 如果您已自动装配 ElasticsearchRestTemplate 以对 elasticsearch 进行非 spring 基于存储库的调用,请将自动装配的候选者更改为父接口 ElasticsearchOperationsElasticsearchRestTemplate 的实例将不会出现在应用程序上下文中

  • ElasticsearchConverter 已在 ElasticsearchConfigurationSupport class 中创建。所以不需要再创建这个bean