一、前言小编最近在制作中遇到了一个问题。解决后马上总结分享给大家。希望能帮到大家!事情是这样的,奇怪的现象,公司自建的ElasticSearch本来是用来提高检索效率的,最近却出错了!版本配置没有变化,很奇怪!ElasticSearch版本是7.6。问题是查询每隔几个小时就查不到,连不上ElasticSearch。刷新后正常查询错误为:java.io.IOException:Connectionresetbypeer。询问;核心原因:本客户端为长链接,过期后服务端自动关闭链接,客户端继续使用原链接导致错误!二、前因后果下面详细说一下错误的原因和解决方法:1、报错信息java.io.IOException:Connectionresetbypeeratorg.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:828)在组织。org.elasticsearch.client.RestClient.performRequest(RestClient.java:248)在org.elasticsearch.client.RestClient.performRequest(RestClient.java:235)在org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514)在org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1484)在org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1454)在org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:970)2.原因及解决办法上面也有说到原因,但不详述。下面我来详细解释一下原因吧!ES会设置一个策略来控制连接时间,设置这个连接的空闲时长!我们可以看一下这个策略:如果不配置我们就按照这个策略。默认-1是长链接,可以回收再利用。我们只需要用我们的策略替换这个策略。@Contract(threading=ThreadingBehavior.IMMUTABLE)publicclassDefaultConnectionKeepAliveStrategy实现ConnectionKeepAliveStrategy{publicstaticfinalDefaultConnectionKeepAliveStrategyINSTANCE=newDefaultConnectionKeepAliveStrategy();@OverridepubliclonggetKeepAliveDuration(finalHttpResponseresponse,finalHttpContextcontext){Args.notNull(response,"HTTPresponse");finalHeaderElementIterator=newBasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));while(it.hasNext()){finalHeaderElementhe=it.nextElement();最终字符串参数=he.getName();最终字符串值=he.getValue();如果(值!=null&¶m.equalsIgnoreCase(“timeout")){try{returnLong.parseLong(value)*1000;}catch(finalNumberFormatExceptionignore){}}}return-1;}}服务器的TCP时间,我们可以查看:cat/proc/sys/net/ipv4/tcp_keepalive_time这里是12分钟,我们需要让客户端的连接时间小于服务器的keepalive时间!这样客户端会在超过时间后重新获取新的连接,从而达到保证不会报错!!3.写具体方案ElasticsearchProperties,获取nacos的信息方便修改!@Data@Component@ConfigurationProperties(prefix="spring.elasticsearch.rest")publicclassElasticsearchProperties{privateStringuris;privateStringusername;privateStringpassword;}编写RestHighLevelClient配置类,使用我们的策略,看到其他教学还是使用之前的连接方式,现在RestClientBuilder中的RestClientBuilder自动建立连接!这里我们注入RestClientBu大哥继续把新攻略放进去吧!由于我们重写了RestHighLevelClient,它依赖于RestClientBuilder,原来RestClientBuilder会自动获取用户名、密码和连接地址。现在我们需要重新分配用户名和密码!这将节省您输入地址的一步!这里设置需要10分钟,但不会超过12分钟!@ConfigurationpublicclassElasticsearchConfig{@AutowiredprivateElasticsearchPropertieselasticsearch属性;@AutowiredprivateRestClientBuilderrestClientBuilder;@BeanpublicRestHighLevelClientrestHighLevelClient(){CredentialsProvidercredentialsProvider=newBasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY,newUsernamePasswordCredentials(elasticsearchProperties.getUsername(),elasticsearchProperties.getPassword()));returnnewRestHighLevelClient(restClientBuilder.setHttpClientConfigCallback(requestConfig->{requestConfig.setKeepAliveStrategy((response,context)->TimeUnit.MINUTES.toMillis(10));requestConfig.setDefaultCredentialsProvider(credq??ueentialsProvider);})return}配置文件:方案二:如果不介意,可以捕获错误,再次调用,第二次会重新建立连接,所以不会有问题,但是不推荐这样!!
