当前位置:

elasticsearch连接过程中的保活问题解决

机器助手 |  2025-07-13
 78人浏览

开发过程中为了提高性能使用到elasticsearch来缓存大量数据,但是使用时候发现使用一段时间不用的时候,再次查询elasticsearch会出现连接错误的问题。这是连接的保活问题

以下是解决方案:// httpclient保活策略

package com.ruoyi.biemo.elasticsearch.util;

import com.ruoyi.biemo.elasticsearch.entity.ElasticsearchMonitorProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * EliasticSearch连接池工厂对象
 *
 */
@Slf4j
@Component
public class ElasticsearchClientPoolFactory implements PooledObjectFactory<RestHighLevelClient> {
    @Autowired
    private ElasticsearchMonitorProperties esProperties;

    @Override
    public void activateObject(PooledObject<RestHighLevelClient> arg0) throws Exception {

    }

    /**
     * 销毁对象
     */
    @Override
    public void destroyObject(PooledObject<RestHighLevelClient> pooledObject) throws Exception {
        RestHighLevelClient highLevelClient = pooledObject.getObject();
        highLevelClient.close();
    }

    /**
     * 生产对象
     */
    @Override
    public PooledObject<RestHighLevelClient> makeObject() {
        RestHighLevelClient restHighLevelClient = null;
        try {
            String[] urlArr = esProperties.getAddress().split(",");
            HttpHost[] httpPostArr = new HttpHost[urlArr.length];
            for (int i = 0; i < urlArr.length; i++) {
                HttpHost httpHost = new HttpHost(urlArr[i].split(":")[0].trim(),
                        Integer.parseInt(urlArr[i].split(":")[1].trim()), "http");
                httpPostArr[i] = httpHost;
            }
            RestClientBuilder builder = RestClient.builder(httpPostArr);

            // 异步httpclient连接延时配置
            builder.setRequestConfigCallback(requestConfigBuilder -> {
                requestConfigBuilder.setConnectTimeout(esProperties.getConnectTimeout());
                requestConfigBuilder.setSocketTimeout(esProperties.getSocketTimeout());
                requestConfigBuilder.setConnectionRequestTimeout(esProperties.getConnectionRequestTimeout());
                return requestConfigBuilder;
            });

            // 异步httpclient连接数配置
            builder.setHttpClientConfigCallback(httpClientBuilder -> {
                httpClientBuilder.setMaxConnTotal(esProperties.getMaxConnectNum());
                httpClientBuilder.setMaxConnPerRoute(esProperties.getMaxConnectPerRoute());
                // httpclient保活策略
                httpClientBuilder.setKeepAliveStrategy(((response, context) -> Duration.ofMinutes(5).toMillis()));
                return httpClientBuilder;
            });
            restHighLevelClient = new RestHighLevelClient(builder);
        } catch (Exception e) {
            log.error("ElasticsearchClientPoolFactory.makeObject error:", e);
        }
        return new DefaultPooledObject<RestHighLevelClient>(restHighLevelClient);
    }

    @Override
    public void passivateObject(PooledObject<RestHighLevelClient> arg0) throws Exception {
    }

    @Override
    public boolean validateObject(PooledObject<RestHighLevelClient> arg0) {
        return true;
    }
}


 

文章评论