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))。
- 方法二
- 方法三
参考
- 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时间内没有报文交互则会主动关闭连接。