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
日志就没再打印了。
相关文章推荐
- 启动Oracle后台服务器的方法_用来检测产生错误的原因,会打印日志
- 【错误记录】python logging日志打印俩次的原因
- 今天打开网站,突然发现sql 2005出现错误:数据库 'mybase_db' 的事务日志已满。若要查明无法重用日志中的空间的原因,请参阅 sys.databases 中的 log_reuse_wait_desc 列。
- C# Maximum request length exceeded. 产生错误的原因,以及解决方法.
- 【收集】hadoop,hbase,zookeeper错误日志及部分解决办法
- Android心得2.5--对应用进行单元测试、打印错误信息和日志输出
- Android心得2.5--对应用进行单元测试、打印错误信息和日志输出
- MOSS中图形化通过记录日志的方式来进行查看“发生意外错误”的原因WSP下载
- 通过log4net配置来打印错误日志
- 安装SQL 2008的错误 等待数据库引擎恢复句柄失败。请查看 SQL Server 错误日志以了解可能的原因
- 标准库函数perror用法(打印出错误原因信息字符串)
- C# Maximum request length exceeded. 产生错误的原因,以及解决方法.
- 标准库函数perror用法(打印出错误原因信息字符串)
- List items=upload.parseRequest(request)错误的原因
- 在我的iOS App中捕获这样的错误日志,什么原因呢?
- 日志(跟后台打印程序系统服务通讯时出现错误)解决办法
- sys.WebForms.PageRequestManagerServerErrorException:错误原因
- 标准库函数perror用法(打印出错误原因信息字符串)
- Jmeter的两个问题:Java Sampler打印日志与Windows下报Address Already in use:connect
- colorbox样式错误的原因排查