SpringBoot项目中ES High Level Rest Client 超时问题排查及解决( 二 )
②抛出异常时间段不固定 。
问题定位
这个问题在之前开发多集群管理平台的时候也出现,当时因为存在③跨版本且还没有正式投产的情况下,并没有太关注的此类问题,觉得此问题可能是版本兼容性 。项目组报上来问题才认真地排查了一番 。
应用系统通过ES High Level Rest Client客户端直连且版本相同,可以排查③的情况 。起初怀疑是查询或者写入量大,后台处理不及时的原因导致异常 。于是查看监控数据和日志,监控显示在几次出现异常的时间点上各项指标这都很正常,没有出现流量陡增的情况,结合现象②,可以排除是因为服务端压力的原因 。
接着把影响异常的源头定位在客户端 。ES客户端和服务端的连接采用的是长连接,查阅源码发现客户端创建了client连接池,每个client持有一个http连接,并且开启http的keep-alive策略复用连接 。正是因为这个复用探活的原因导致该异常发生 。下面具体分析该问题 。
问题分析
在未处理前restClient客户端创建示意代码:
final RestClientBuilder restClientBuilder =RestClient.builder(redisHostList).setRequestConfigCallBack(requestConfigBuilder -> {;requestConfigBuilder.setConnectTimeout(5000);requestConfigBuilder.setSocketTimeout(60000);requestConfigBuilder.setConnectionRequestTimeout(500);return requestConfigBuilder;}).setHttpClientConfigCallback((httpAsyncClientBuilder) -> {httpAsyncClientBuilder.disableAuthCacheing();return httpAsyncClientBuilder;final RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);
客户端与服务端的连接示意图:

文章插图
ES high-level-client 对长连接的实现是把超时时间设置为-1,意味着客户端永远不超时,服务端设备为了资源的利用率会检测与此设备的连接是否在使用,如果一个连接长时间没有使用,服务端会主动把这个连接关闭,而此时客户端不知情,还处在连接状态,可以说当前处于半连接状态 。当有流量进来的时候使用了该连接就会发现与服务端连接不上,产生timeout,客户端也断开此链接,如上图 1 所示 。客户端使用新连接 2 与服务端通信 。因此问题的根源在于客户端没有及时发现连接的不可用并断开,因此需要设置让客户端主动对tcp连接进行探测保活 。
解决方案
一、客户端显式的设置setKeepAliveStrategyhttpAsyncClientBuilder.setKeepAliveStrategy((httpResponse,httpContext) -> TimeUtils.MINUTES.toMillis(3))二、显示开启 tcp keepalivehttpAsyncClientBuilder.setDefaultIOReactorConfig(IOReactorConfig.sustom().setSoKeepAlive(true).build())三、在系统层面设置tcp keepalive探测保活时间net.ipv4.tcp_keepalive_time = 60
来源:https://www.modb.pro/db/388569
【SpringBoot项目中ES High Level Rest Client 超时问题排查及解决】
推荐阅读
- 使用SpringBoot+Vue开发的智慧小区物业管理系统源码
- 金鹰奖|恭喜!31届金鹰奖颁奖礼看点多,各奖项众望所归,何炅多次救场
- 痛经宝颗粒有副作用吗?保痛经颗粒的注意事项
- 如何在雾霾天里做好自我防护? 雾霾天气注意事项
- 泰国旅游注意事项有哪些 去泰国旅游注意事项
- 骨灰盒下葬的几大注意事项及禁忌,火葬后骨灰盒放哪-
- 金鹰奖|重要奖项爆冷,这届金鹰奖没有“女神”,多了许多“男神”
- 金鹰奖|金鹰奖:提名名单开出“死亡之组”,演员单项奖竞争异常激烈
- 体检前有哪些注意事项? 体检前一天注意什么?
- 项羽为何不杀刘邦(鸿门宴上项羽为什么不杀刘邦?)