一:背景
数据查询的时候发现数据已经更新了,但是查到的数据还是老的,由此引出此问题。
二:解决问题
线上问题已经发生了,肯定是要保持线上业务先正常运行,然后再去查找具体问题原因。解决问题步骤:
腾讯订阅同步服务器是否有问题 ,如果有问题重启,如果没问题进入步骤2
服务是否有错误日志
如果同步服务有问题,重启
执行全量同步逻辑
在此过程中,我看了下腾讯云服务器此时是正常的,也看了下同步服务的错误发现都是一些链接问题,而且都是交易相关的es集群,其他es集群没有报这个错误,而且这个错误后来一直都存在(问题疑问点,不是业务异常,问什么链接一直被拒绝???)。此时执行了下全量数据同步的job发现还是报如下图中的错误,开始怀疑同步服务有问题,于是就重启同步服务,然后重新跑了同步job,发现这次任务执行成功了,业务也正常了。开始思考,问什么会出现这种问题。具体细节如下
三:问题复盘定位1. 去查看es集群健康状态,看是不是es集群服务器有问题,因为前段时间出现过es服务器失联的情况,下边是失联时候的截图,
后来登陆es集群服务器发现,es集群健康状态良好,排除es集群故障原因
2. 查看ES同步服务是否正常
去es同步服务看了下,服务也正常的在跑,只是每次同步再向es发请求的时候,都是报的和上边图中一样的问题。
Request cannot be executed; I/O reactor status: STOPPED
后边为了保证业务能够尽快恢复就去跑了下全量同步的job,发现跑了全量同步数据job也是报这个异常,仔细想了下,又去网上搜索了下相应报错关键字
看到这个,就有点眉目了,是不是同步服务拿到的ES链接已经是不可用的,于是重启了同步数据服务,然后再次跑了同步服务,发现这次竟然成功了。
3. 具体问题分析
线上业务正常运行,开始追溯为什么会出现这种问题。想到上边提到的 一般在出现 be ; I/O : 这种问题的时候都会有 I/O 这个报错,于是我去日志平台去搜了下,发现还真有,并且在出现 : 之前。
这时候就开始怀疑是不是es服务器这时候有问题重启或者有其他操作。于是就去es服务器上查看这个时间段的日志,日志如下。
结果看到这里大概明白了80% ,这里是es服务器,节点挂了,并且断开了链接,同步进行了选主,以及后续的主从数据同步。
从上边搜索的可以看到如下关键信息:
发现CloseableHttpAsyncClientBase的status状态的修改都被封装在CloseableHttpAsyncClientBase中,一旦状态为STOPPED之后就状态将不再可用。
CloseableHttpAsyncClientBase的close方法在被调用以后,会执行构造方法中的线程:reactorThread,这个线程里会去重置CloseableHttpAsyncClientBase中的状态为Active,但是因为发生了异常,所以打印了这个日志
于是明白了,原来链接关闭了,后边的链接状态一直处于 状态,所以会一直报 I/O : 。
那么疑问来了:为什么在es服务器正常了之后,没有重连,或者连接状态检测呢???
我随后有看到了一个关键信息:
发现在 at org..http.nio..utor. 这个方法中竟然有报错,大概意思就是 没有 在这个方法中 用到 ption 但是没有 ption初始化方法,于是去找源码看
发现里边确实用到ption 并且用到了无参数构造函数,于是点进去看ption 内部是怎么样的 ,大吃一惊:
发现里边竟然没有无参构造函数,所以报出了init失败。
猜想:
于是想到版本问题,去找,当前方法所在的包:
后续升级了这个包,发现依然不对,于是去网上查了下,发现真正影响的包是 -core于是升级推荐的包。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.12</version>
</dependency>
升级之后如下图:
此时无参数构造函数已经有了,后续发上去代码,后续在本地也进行了测试,后续能够自动重连。
总结
导致 be ; I/O : 的错误是由于I/O 线程异常退出导致
导致程序在方法里判断连接状态是无效的原因,目前发现有两种:
解决方式: