您的位置:首页 > 产品设计 > UI/UE

Zookeeper不停打印错误日志NoClassDefFoundError原因排查,ConnectRequest

2017-01-16 16:37 423 查看
最近发现联调环境上,某web应用日志频繁报下面的错误:

2017-01-11 13:48:51.619  WARN 385 --- [68.124.11:2181)] org.apache.zookeeper.ClientCnxn          : Session 0x0 for server 10.168.124.11/10.168.124.11:2181, unexpected error, closing socket connection and attempting reconnect

java.lang.NoClassDefFoundError: org/apache/zookeeper/proto/ConnectRequest
at org.apache.zookeeper.ClientCnxn$SendThread.primeConnection(ClientCnxn.java:857) ~[zookeeper-3.4.6.jar!/:3.4.6-1569965]
at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:363) ~[zookeeper-3.4.6.jar!/:3.4.6-1569965]
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1081) ~[zookeeper-3.4.6.jar!/:3.4.6-1569965]


虽然web服务也能正常执行,但log日志一直不停地打,这肯定是不行的。刚开始看到NoClassDefFoundError这个错,以为又是缺包少类,或者jar包冲突。但是这个类是ZK的核心包里的类,按道理不应该会没有jar包。况且NoClassDefFoundError和NoClassException多少还是有些区别的。

于是胸有成竹自以为是jar包冲突,就把spring-boot打的web-jar包解开,结果lib目录下,仅有一个zookeeper-3.4.6.jar,还有一个zkCLient的jar包。于是jar包冲突被排除了。 

无奈,只能在网上寻觅答案了。搜索了一会,网上只能找到下面的错误排查原因:

java.lang.NoClassDefFoundError: org/apache/zookeeper/proto/SetWatches

   看了看里面介绍的详细原因:(原文请参看:http://blog.csdn.net/hengyunabc/article/details/41450003)
    这个异常的原因,是某些zookeeper的类没有加载到。

最终原因分析

梳理下整个流程:

Tomcat启动,初始化webcontext;
初始化spring, spring初始某些些bean,这些bean包括了zookeeper的连接相关的bean;
这时zkClient(独立线程)已经连接上服务器了,但是classloader没有加载到org/apache/zookeeper/proto/SetWatches类;
spring初始化失败,导致Tomcat webcontext初始化也失败,应用在挂起状态,但zkClient线程还是正常的;
zookeeper服务器重启,zkClient开始重连,连接上zookeeper服务器;
zkClient触发watch的一些代码,ClassLoader尝试加载org/apache/zookeeper/proto/SetWatches类,但是发现找不到类,于是抛出异常;
zkClient捕获到异常,认为重连失败,close掉connection,休眠几秒之后,再次重连;
于是出现了zkClient反复重试连接zookeeper服务器,而且都是秒连秒断的情况。

总结一下:java.lang.NoClassDefFoundError: org/apache/zookeeper/proto/SetWatches的原因是由于应用程序没有正常启动,而zkClient线程在应用程序进程启动失败前已经正常启动了,所以导致zkClient没有在jvm中找到SetWatches该类。
由于下面两个问题太相似,所以我大胆猜测产生原因是相同的,于是去查机器上的java进程。ps -ef | grep java

java.lang.NoClassDefFoundError: org/apache/zookeeper/proto/ConnectRequest
java.lang.NoClassDefFoundError: org/apache/zookeeper/proto/SetWatches
果然,发现了在服务器上有三个相同应用程序进程:


也就是说,前面两个都是启动失败挂起状态。而最后一个是成功的,所以web服务能正常服务,但同样385或者

585也在不停往log日志中循环输出。这一定是某个粗心的同事干的好事。启动之前不知道先杀掉旧进程。


最后,解决办法:把385和585进程杀掉。kill -9 385 && kill -9 585

日志就没再打印了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐