Elasticsearch长时间不操作再新增文档时超时Connect Rest

392 阅读1分钟

问题现象是: 在Springboot启动后,进行一次文档操作增删改查等,之后空闲大概不到十分钟,在进行文档操作时会抛出异常Connect Rest,抛出此次异常后再次进行文档操作又恢复了正常。感觉原因应该是第一次操作之后连接一直在空闲状态Elasticsearch端关闭了空闲了连接导致第二次操作发生了异常,因为此时elasticsearch-java产生的RestClient并不知道Elasticsearch已经关闭了连接,第三次操作文档时因为第二次连接发生了异常所以新建了连接,此时又恢复了正常。

环境:

  1. Elasticsearch8.10.4
  2. spring-boot-starter-data-elasticsearch 3.1.5

解决方案: 给RestClientBuilder的HttpAsyncClientBuilder属性设置保活策略

参考自:spring data elasticsearch: 设置保活策略|长时间不连接es,报错超时连接_setkeepalivestrategy-CSDN博客

这位大佬给出的方案对我的项目来说有些美中不足,因为我使用的是boot-starter,如果自己创建一个RestClient(es8以后使用elasticsearch-java,这位大佬使用的是RestHighLevelClient)的Bean,就无法完美适配spring-boot-starter-data-elasticsearch提供的参数配置。

通过阅读源码发现其实spring-boot-starter-data-elasticsearch提供了RestClientBuilder这个bean的扩展点RestClientBuilderCustomizer接口,实现该接口后可以在创建RestClientBuilder这个bean时定义一些属性,比如HttpAsyncClientBuilder。

源码位置 org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration#elasticsearchRestClientBuilder 1699274718442.png

我们可以自定义一个Bean实现RestClientBuilderCustomizer接口,来定义HttpAsyncClientBuilder的属性 代码如下:

/**
 * Spring-data-elasticsearch-starter的回调,用于自定义RestClientBuilderBean的属性
 * */
@Component
public class KeepAliveStrategyRestClientBuilderCustomizer implements RestClientBuilderCustomizer {
    @Override
    public void customize(RestClientBuilder builder) {}

    /**
     * 设置连接保活策略为1分钟
     * */
    @Override
    public void customize(HttpAsyncClientBuilder builder) {
        builder.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
                    @Override
                    public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
                        return Duration.ofMinutes(1).toMillis();
                    }
                });
    }
}