程序日志停止滚动问题排查

今天在做定时任务的时候,遇到了一个比较难搞的问题,这个问题也比较有意思,现在给大家分享一下,这个定时任务的调用入口是这样的。

// 进行 ldap同步
public void  runLdapSyncJob(){
    try {
        ldapSyncService.syncLdap();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这个方法ldapSyncService.syncLdap()向外抛出异常,这个方法内部会调用另一个方法

/**
 * 创建部门目录并返回部门cn
 * @param departmentDtoMap
 * @param targetDepartId
 * @param rootCn
 * @return
 * @throws Exception
 */
public  String creatStaffDepartCN(Map<Long,DepartmentDto> departmentDtoMap ,long targetDepartId,String rootCn, Set<String> ldapDUSet ) throws Exception {}

但是传入的参数中,第二个参数传入的是Long类型,而且是null,一开始没排查出来,因为一直加日志,在调用处,数据返回处,数据验证处都加日志了,但是通过定时任务管理平台执行任务之后方法执行到一定行数就什么也没有了,也没有日志,怀疑是可能有死循环(程序里写了while)结果top一下,发现cpu,内存都很正常,结合之前遇到的这种情况也看了下这个定时任务的进程线程状态,看看有没有blocked或者死(单线程操作应该不会有死锁),发现也没有。

这就尴尬了,于是想到了可能异常被框架或者jvm吃掉了,于是在上面两个方法里都加了try,catch

ldapSyncService.syncLdap() throws Exception{

try{

……

}catch(Exception e){

e.print();

}

}

creatStaffDepartCN() throws Exception{

try{

……

}catch(Exception e){

e.print();

}

}

再次部署执行之后发现确实有异常了,然后抛出了空指针,这里我恍然大悟,因为creatStaffDepartCN这个方法的第二个入参确实没有值传进去的。然后怀疑是否是因为自动装箱和拆箱过程中即使出现异常也会被jvm吃掉。本地简单写了一个demo,运行发现会报空指针。

这里没有打印异常我判断有下面几种可能

1.定时任务框架没有帮忙抛出。

2.最外层的try,catch没有生效

3.jvm把异常吃掉了

下面总结一下遇到程序日志停止滚动之后我们可以做的一些操作

1.top看是否由于FGC等问题导致的服务停止响应

2.jstack -l pid看一下进程内线程是否大量有blocked状态的线程

3.在日志停止滚动的代码上下文增加try,catch语句尝试捕获异常。

本文由博客一文多发平台 OpenWrite
发布!

架构设计@工程设计@服务稳定性之路

原文 

http://www.cnblogs.com/coderManFans/p/11851995.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 程序日志停止滚动问题排查

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址