本文来自网易云社区
作者:苏鹏
最近部门的某产品周末时候测试服务器下会无故宕机,周一测试的同学来问具体原因,综合周末收到的哨兵系统的报警,简单分析了现象,应该是后台服务的原因。
在项目部署的时候需要加上一个参数,即-XX:+HeapDumpOnOutOfMemoryError,等OOM的时候会把内存文件DUMP出来
这时候我们发现内存文件已经生成在我们设置的路径下了
4.使用java visualVM分析该内存文件
(1)使用scp命令把该内存文件下载到本地,具体操作略
(2)打开java visualVM应用
我用的是mac系统,不熟悉的小伙伴可能不知道它存在的位置,这里也给大家写一下jdk自带工具的路径
/Library/java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin
(3)导入内存文件后,在java visualVM中可以看到该文件的简介
我们可以看到我们的visualVM已经为我们展示了各个线程的状态。
然后搜索一下状态为BLOCK状态的线程
我们发现BLOCK状态的线程,它们所指向的代码都是同一个,MMLogger是我们封装的日志文件,难道会出什么问题?
5.分析代码
定位到我们具体的代码问题,那我们接下来就来分析代码,我们发现了两个问题
(1)在AOP中我们配置了所有进入接口都会打印一个日志
execution(public * com.netease.ai.ar.dongjian.web..*.* (..))"
(2)使用日志的方式不正确
我们使用的是 org.apache.log4j.LogManager;
其中跟踪代码下去,就会发现会进入到这个方法
会有这样的一个代码段有关键字,在并发量比较高的情况下可能会出现死锁的情况
总结:综合以上两个原因,就会造成同时会有很多线程在打印日志,而打印日志又会进入到synchronize代码段,造成很多的线程都在等待这段代码执行完,导致了BLOCK的产生
以上两个方面,我们分别解决
(1)把进入所有接口日志配置去除,改成有需要的接口加日志注解的方式
(2)修改日志类,改为org.slf4j.LoggerFactory;
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区。