前语

前段时刻上线了个项目,测验每天早上来摸鱼之前会点一点,发现第一次点会报错,然后一天都没问题,刚开始没在意,后来每天上班来摸鱼前点第一次都会出错,发现真springboot面试题的摸到鱼了,然后就给我提了个bug,说明日早上第一java模拟器次留给你,你复现一下看看,然后就有了这篇文章了。

问题现象

ES隔一段时刻不操作后,再恳求es就会报错Connection re架构setjava编译器 by peer,之后连续几次操作都正常,而且还是必现的,报错信息如下:

org.springframework.dao.DataAccessResourceFailureException: Connection reset by peer; nested exception is java.lang.RuntimeException: Connection reset by peer
  at org.springframework.data.elasticsearch.core.ElasticsearchExceptionTranslator.translateExceptionIfPossible(ElasticsearchExceptionTranslator.java:76)
  at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.translateException(ElasticsearchRestTemplate.java:378)
......
Caused by: java.io.IOException: Connection reset by peer
  at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:828)
  at org.elasticsearch.client.RestClient.performRequest(RestClient.java:248)
  at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235)
  at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514)
......
Caused by: java.io.IOException: Connection reset by peer
  at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
  at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
  at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
......

问题定位

Caused by: Connspringcloudection reset by peer根据日志能够知道,socket 衔接被中spring翻译止,衔接中止的原因有很多,比方:

  • 服务端或许客户端反常。
  • 客户端衔接超时中止。

检查日志,这段时刻内也没啥反常信息,服务端也没反mysql数据库命令大全常重启,也没呈现流量陡量的状况。想到之前在mysql遇到过的问题,mysql的衔接假如超越8个小时(默认的时刻)不衔接,服务端为了节约资linux系统安装源,会主动把spring翻译长时springboot刻没衔接的客springboot面试题户端给中止掉,依照这个思路去排查问题,果然发现原因如出一辙。导致这个问题的原因有两个:

  1. 客户端选用长衔接的办法衔接服务端。
  2. 长时刻不连ES,服务端会关闭衔接。

1java模拟器. 客户端选用长衔接的办法衔接服务端, 一向持有衔接。

ES High Level Rest Client客户端和服务端的衔接选用的是长衔接,查阅源码发现客户端创建了clielinux创建文件nt衔接池,每个client持有一个http衔接,并且开启http的keep-alive战略复用衔接, 战略默认是 -1 ,也就是不linux是什么操作系统过期。

ES两个小时没衔接竟然会呈现bug,为此老板给我夹了个鸡腿。。。

2. 长时刻不连ES,服务端会关闭衔接。

服务器会有TCP的Keepalive 经过一段时刻假如没有操作就会主动断MySQL开衔接功能,而ES默认就是取服务器的时长装备linux检查超时时刻默认为两小时:

# 检查超时时刻(单位秒)
[root@VM ~]# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

也就是说假如客户端超越两个小时没有衔接服务端,服mysql索引务端会linux常用命令清除去衔接。

解决办法

修改客户端的keepalivelinux虚拟机时刻,以单机的ES为例,代码如下:

@Override
public RestHighLevelClient elasticsearchClient() {
  List<HttpHost> httpHostsList = new ArrayList<>();
  httpHostsList.add(new HttpHost(uris, Integer.parseInt(port)));
  HttpHost[] httpHostsArray = new HttpHost[httpHostsList.size()];
  httpHostsArray = httpHostsList.toArray(httpHostsArray);
  RestClientBuilder builder = RestClient.builder(httpHostsArray);
  builder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setKeepAliveStrategy((httpResponse, httpContext) -> 1000 * 60));
  return new RestHighLevelClient(builder);
}

applicatiolinux重启命令n.yaml

spring:
  elasticsearch:
   rest:
    uris: ip
    port: port

以上代码是基于单机mysql安装配置教程版的es装备的,假如你们的是集群请自行百度设置,重点代码是设置setKeepAliveStrategy 这个办法里面。

经过这个设置后,线上就没有呈现过相似的问题了。

最终

其实这个问linux常用命令题不仅仅是ES会有的,mysql, CK, 还有其他同类的C/S架构的都会存在这样的问题,这是一类问题,因为服mysql数据库命令大全务端资源优化,会收回一些衔接,就会导架构图怎么制作致这个问题,知道这个问题mysql基础命令后,咱们能够触类旁通,遇到同样的问题能够快速定位,希望这个问题能对大家有用,最终感谢大家看到这里。。。