
# 使用Spring Boot访问Elasticsearch出现Connection reset by peer问题
#### 问题现象
Spring Boot服务使用Elasticsearch RestHighLevelClient接入Elasticsearch集群，运行一段时间后，出现报错"Connection reset by peer"，TCP连接中断，业务数据写入失败。
#### 原因分析
连接关闭有很多原因，是Elasticsearch服务器端不能完全控制的。例如，有可能是服务器端关闭了连接，有可能网络中有防火墙、交换机、VPN等，也有可能是keepalive设置问题，更换了连接服务器节点，网络不稳定等。
#### 处理步骤
如果出现这种情况可以参考如下多种方式解决问题。
- 方法一 修改RestHighLevelClient连接请求的超时时间 ，默认1000ms可以尝试增加到10000ms。
  ```
  RestClientBuilder builder = RestClient.builder(new HttpHost(endpoint, port))
          .setHttpClientConfigCallback(httpClientBuilder->    
  httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
          .setRequestConfigCallback(requestConfigBuilder ->
  requestConfigBuilder.setConnectTimeout(10000).setSocketTimeout(60000));
      return new RestHighLevelClient(builder);
  ```
  单个请求修改：request.timeout(TimeValue.timeValueSeconds(60))。
  
- 方法二 设置RestHighLevelClient keepalive时间，建议设置到15分钟。
  
- 方法三 针对代码层面捕获异常情况，建议重试请求。
  
 
#### 参考信息
- TCP长连接和短连接 TCP协议中有长连接和短连接之分。短连接在数据包发送完成后会自己断开，长连接在发包完成后， 会在一定的时间内保持连接，即通常所说的Keepalive（存活定时器）功能。
  
- TCP保活机制 保活机制是由一个保活计时器实现的。当计时器被激发，连接一端将发送一个保活探测报文， 另一端接收报文的同时会发送一个ACK作为响应。 如果客户端无响应，服务器将中断连接，否则会重置保活计时器。
  服务器端Keepalive设置时间30m，Linux有三个参数可以控制保活时间： tcp_keepalive_time（开启Keepalive的闲置时长）、 tcp_keepalive_intvl（Keepalive探测包的发送间隔）、tcp_keepalive_probes （如果对方不予应答，探测包的发送次数）。
  
- http-keepalive http-keepalive是保证一个TCP连接尽可能传递多的报文，每次交互一个报文后就会更新http-keepalive时间。如果http-keepalive时间超时，意味着这段时间client和server没有报文交互，本端会主动关闭释放连接。
  tcp-keepalive是一种探测TCP连接状态的保活机制，TCP连接建立后如果不主动关闭，client和server没有发生异常，这个连接理论上是一直存在的，http-keepalive是保证一个TCP连接上尽可能传递更多的报文，如果http-keepalive时间内没有报文交互则会主动关闭连接。
  
 
