如何在Spring Boot项目中配置多个Elasticsearch连接并实现索引隔离?
直接复制配置类无法生效的原因
直接复制原配置类替换参数无法正常运行,Spring启动时会检测到两个同类型同名称的RestHighLevelClient Bean,抛出Bean定义冲突异常。
双ES实例接入+索引隔离实现方案
1. 定义两个独立的ES客户端Bean
首先编写多ES配置类,给两个实例的Bean设置不同的名称,避免冲突:
@Configuration public class EsMultiClientConfig { // 第一台ES实例客户端 @Bean("esClientServer1") public RestHighLevelClient esClientServer1() { CredentialsProvider cp = new BasicCredentialsProvider(); cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("server1用户名", "server1密码")); return new RestHighLevelClient(RestClient.builder(new HttpHost("server1地址", server1端口, "https")) .setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(cp) .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()))); } // 第二台ES实例客户端 @Bean("esClientServer2") public RestHighLevelClient esClientServer2() { CredentialsProvider cp = new BasicCredentialsProvider(); cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("server2用户名", "server2密码")); return new RestHighLevelClient(RestClient.builder(new HttpHost("server2地址", server2端口, "https")) .setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(cp) .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()))); } }
2. 实现索引按实例隔离
你要求的entity1存server1、entity2存server2的需求完全可以实现,按Repository包路径拆分绑定对应客户端即可:
- 新建两个Repository包:
com.yourproject.repository.es1(存放server1对应的实体操作类)、com.yourproject.repository.es2(存放server2对应的实体操作类) - 分别编写两个Repository配置类,绑定不同包和对应ES客户端:
server1对应Repository配置
@Configuration @EnableElasticsearchRepositories( basePackages = "com.yourproject.repository.es1", elasticsearchTemplateRef = "esTemplateServer1" ) public class Es1RepositoryConfig { @Bean public ElasticsearchOperations esTemplateServer1(@Qualifier("esClientServer1") RestHighLevelClient esClientServer1) { return new ElasticsearchRestTemplate(esClientServer1); } }
server2对应Repository配置
@Configuration @EnableElasticsearchRepositories( basePackages = "com.yourproject.repository.es2", elasticsearchTemplateRef = "esTemplateServer2" ) public class Es2RepositoryConfig { @Bean public ElasticsearchOperations esTemplateServer2(@Qualifier("esClientServer2") RestHighLevelClient esClientServer2) { return new ElasticsearchRestTemplate(esClientServer2); } }
后续将entity1对应的Repository放在es1包下,entity2对应的Repository放在es2包下,操作时会自动路由到对应ES实例,自动实现索引隔离。如果不用Spring Data ES的Repository,直接注入客户端时加@Qualifier指定Bean名称即可:
// 注入server1客户端操作entity1 @Autowired @Qualifier("esClientServer1") private RestHighLevelClient esClientServer1; // 注入server2客户端操作entity2 @Autowired @Qualifier("esClientServer2") private RestHighLevelClient esClientServer2;
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

