配置Elasticsearch多数据源(非集群)

SpringBoot集成多个Elasticsearch7.6.2

如果是集成一个或者Elasticsearch集群,可以用springboot的自动装配。以下是集成多个毫无关系的elasticsearch客户端

  1. pom.xml导入依赖
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.8.0</version>
        </dependency>
  1. 配置config工厂类

import lombok.Data;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.time.Duration;;


/**
 * ES配置
 */
@Data
@Configuration
@Component
@ConfigurationProperties(prefix = "elasticsearch")
public class EsConfig {

    public static final String ES_CLIENT_1 = "es_client_1";
    public static final String ES_CLIENT_2 = "es_client_2";

    private Connect connect1;
    private Connect connect2;

    /**
     * 客户端1
     */
    @Bean(name = ES_CLIENT_1, destroyMethod = "close")
    public GenericObjectPool<RestHighLevelClient> genericObjectPool1() {
        return esPool(factoryClient(connect1), config());
    }

    /**
     * 客户端2
     */
    @Bean(name = ES_CLIENT_2, destroyMethod = "close")
    public GenericObjectPool<RestHighLevelClient> genericObjectPool2() {
        return esPool(factoryClient(connect2), config());
    }

    private GenericObjectPool<RestHighLevelClient> esPool(PooledObjectFactory<RestHighLevelClient> factory, GenericObjectPoolConfig config) {
        return new GenericObjectPool<>(factory, config);
    }

    private GenericObjectPoolConfig config() {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMinIdle(5);
        poolConfig.setMaxIdle(20);
        poolConfig.setMaxTotal(500);
        poolConfig.setMaxWaitMillis(3000L);
        poolConfig.setJmxEnabled(false);
        return poolConfig;
    }

    private PooledObjectFactory<RestHighLevelClient> factoryClient(Connect connect) {
        return new BasePooledObjectFactory<RestHighLevelClient>() {
            @Override
            public void destroyObject(PooledObject<RestHighLevelClient> pooledObject) throws Exception {
                RestHighLevelClient highLevelClient = pooledObject.getObject();
                highLevelClient.close();
            }

            @Override
            public RestHighLevelClient create() throws Exception {
                return getRestHighLevelClient(connect);
            }

            @Override
            public PooledObject<RestHighLevelClient> wrap(RestHighLevelClient restHighLevelClient) {
                return new DefaultPooledObject<>(restHighLevelClient);
            }
        };
    }

    private RestHighLevelClient getRestHighLevelClient(Connect connect) {
        HttpHost host = HttpHost.create(connect.hosts);
        RestClientBuilder builder = RestClient.builder(host);
        // 异步连接延时配置
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(connect.connectTimeout);
            requestConfigBuilder.setSocketTimeout(connect.socketTimeout);
            requestConfigBuilder.setConnectionRequestTimeout(connect.connectionRequestTimeout);
            return requestConfigBuilder;
        });
        // 异步连接数配置
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setMaxConnTotal(connect.maxConnectNum);
            httpClientBuilder.setMaxConnPerRoute(connect.maxConnectPerRoute);
            httpClientBuilder.setKeepAliveStrategy(((response, context) -> Duration.ofMinutes(3).toMillis()));
            return httpClientBuilder;
        });
        return new RestHighLevelClient(builder);
    }

    @Data
    public static class Connect {

        private String hosts;
        /**
         * 连接超时时间
         */
        private int connectTimeout;
        /**
         * Socket 连接超时时间
         */
        private int socketTimeout;
        /**
         * 获取连接的超时时间
         */
        private int connectionRequestTimeout;
        /**
         * 最大连接数
         */
        private int maxConnectNum;
        /**
         * 最大路由连接数
         */
        private int maxConnectPerRoute;
    }
}

ES连接池:

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class EsClientPool {

    @Autowired
    @Qualifier(ElasticsearchConfig.ES_CLIENT_1)
    private GenericObjectPool<RestHighLevelClient> genericObjectPool1;

    @Autowired
    @Qualifier(ElasticsearchConfig.ES_CLIENT_2)
    private  GenericObjectPool<RestHighLevelClient> genericObjectPool2;

    /**
     * 获得对象
     *
     * @return
     * @throws Exception
     */
    public RestHighLevelClient getClient(Integer a) throws Exception {
        // 从池中取一个对象
        if(a==1){
            return genericObjectPool1.borrowObject();
        }else {
            return genericObjectPool2.borrowObject();
        }
    }

    /**
     * 归还对象
     *
     * @param client
     */
    public void returnClient(RestHighLevelClient client, Integer a) {
        // 使用完毕之后,归还对象
        if (a== 1) {
            genericObjectPool1.returnObject(client);
        } else {
            genericObjectPool2.returnObject(client);
        }
    }
}

  1. 在yml中加入以下配置
elasticsearch:
  connect1:
    hosts: http://127.0.0.1:9200
    connectTimeout: 10000
    socketTimeout: 10000
    connectionRequestTimeout: 1000
    maxConnectNum: 500
    maxConnectPerRoute: 200
  connect2:
    hosts: http://127.0.0.1:9200
    connectTimeout: 10000
    socketTimeout: 10000
    connectionRequestTimeout: 1000
    maxConnectNum: 500
    maxConnectPerRoute: 200
  1. 需在springboot中的启动类中关闭ES的自动装配(在@SpringBootApplication注解加上exclude = {RestClientAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})跟用上@EnableConfigurationProperties(EsConfig.class)
@EnableConfigurationProperties(EsConfig.class)
@SpringBootApplication(exclude = {RestClientAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})
public class XXXXApplication {}

5.在impl中写(索引如果是通配符*方式请注意如果索引太多个可能会查询超时):

@Service
@Slf4j
public class EsImpl {

 	@Autowired
    private EsClientPool esClientPool;
    
	public void getEs(DTO dto) {
		 BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        // 创建搜索请求对象
        SearchRequest request = new SearchRequest();
    		//索引名称,通配符*方式请注意如果索引太多个可能超时
        request.indices("XXX_2022-10*");
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //多条件设置
        boolBuilder.must(QueryBuilders.termQuery("xxx", dto.getXXX()));
        sourceBuilder.sort("createDate", SortOrder.DESC);
        sourceBuilder.from(dto.getPageIndex()-1);
        sourceBuilder.size(dto.getPageSize());
        sourceBuilder.query(boolBuilder);
        request.source(sourceBuilder);
        RestHighLevelClient client = null;
        SearchResponse response = null;
        try {
        	// 1跟2分别代表不同的客户端
            client = esClientPool.getClient(1);
            response = esClientPool.getClient(1).search(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ES search fail=", e);
        } finally {
            if (client != null) {
                esClientPool.returnClient(client, 1);
            }
        }
        SearchHits hits = response.getHits();
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ElasticsearchRepository是Spring Data Elasticsearch库中的一个抽象仓库接口,它提供了对Elasticsearch搜索引擎的CRUD操作支持。当需要管理多个独立的数据(例如不同的索引或集群)时,可以在配置中设置ElasticsearchRepository的多数据功能。 在Spring Boot项目中,你可以按照以下步骤配置ElasticsearchRepository的多数据: 1. 定义多个`@Configuration`类,每个类对应一个数据,其中包含ElasticsearchTemplate或者ElasticsearchRestTemplate的实例和相关的配置信息,如连接URL、认证等。 ```java @Configuration public class DataSourceA { @Bean public ElasticsearchOperations elasticsearchOperationsA() { // 配置A的数据 return new RestHighLevelClient( RestClient.builder(Arrays.asList(new HttpHost("localhost", 9200, "http")))); } } @Configuration public class DataSourceB { @Bean public ElasticsearchOperations elasticsearchOperationsB() { // 配置B的数据 return new RestHighLevelClient( RestClient.builder(Arrays.asList(new HttpHost("localhost", 9201, "http")))); } } ``` 2. 在`ElasticsearchRepository`的实现类上,你可以通过注解`@EnableScanForRepositories(basePackages = ..., repositoryBaseClass = MyRepository.class)`指定扫描哪些包下的Repository,并添加`@Autowired`注解绑定到对应的`ElasticsearchOperations`。 ```java @EnableScanForRepositories(basePackages = {"com.example.repository.datasourceA", "com.example.repository.datasourceB"}, repositoryBaseClass = MyRepository.class) public class RepositoryConfig { @Autowired private ElasticsearchOperations operationsA; @Autowired private ElasticsearchOperations operationsB; } ``` 3. 在Repository接口方法中,你可以使用`@Autowired`注解直接注入相应的`ElasticsearchOperations`,根据上下文选择正确的数据。 ```java @Repository public interface MyRepository extends ElasticsearchRepository<MyDocument, String> { @Autowired ElasticsearchOperations operations; List<MyDocument> findByDataSource(@Value("${elasticsearch.data.source}") String dataSource); } ``` 当你调用`findByDataSource`方法时,Spring会自动识别哪个数据对应于当前的上下文环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值