大家好,欢迎来到IT知识分享网。
同事的项目有时候会卡住,重启之后就好了。下面是分析过程
业务线程调用是交由spring管理的,设置好调用频次,调用完成即结束,一般线程耗时都很少
1、获取耗时较长的线程id
top -Hp java进程ID 这个是以cpu使用高低对线程进行排序
因为这次的问题不是cpu飚高,而是业务跑不下去导致的,所以重点在于查看时间过长的线程,举个粟子: 9335最高,以此为切入点
2、获取栈信息
命令:jstack 进程id > jstack.log
3、分析栈内容
- 把栈信息发到本地便于处理
- 将线程id转换为16进制, 1)可以在电脑自带的计算器里面计算 2)也可以在linux printf “%x\n” 10进制的进程id
- 9335的16进制为 2477 ,搜索栈内容发现在等待 waiting to lock <0x00000006165e71f0>
- 我这边用的是notepad++,搜索【0x00000006165e71f0】,结果为有13次匹配,
- 搜索》书签》复制书签行 可以把选中的复制到新窗口粘贴,不会此方法的,可以搜 locked <0x00000006165e71f0 也可以快速定位目前是哪个模块在使用此锁
- 复制下面标红的一行在一开始导出的栈文件里面搜索就可以定位是哪个模块在使用此锁
下面是部分代码块,我们可以确定是卡在数据库这一块了,可能是数据库死锁导致代码死锁,我们这边对并发要求不高,是将锁加到方法上面的,一个方法锁住了,业务就停掉了。
到这里就已经定位到问题了,但是也有可能是获取栈信息时,当时这个业务模块下好拿到了锁资源,正常在跑,建议栈内容多拉一份做比对更好
appScheduler-11" prio=10 tid=0x00007f6734c8e800 nid=0x2481 runnable [0x00007f6703ffd000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:153)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
- locked <0x0000000617641020> (a com.mysql.jdbc.util.ReadAheadInputStream)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2911)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3337)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3327)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530)
- locked <0x00000006176410c8> (a com.mysql.jdbc.JDBC4Connection)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907)
- locked <0x00000006176410c8> (a com.mysql.jdbc.JDBC4Connection)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2030)
- locked <0x00000006176410c8> (a com.mysql.jdbc.JDBC4Connection)
at
。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
at cn.xxxx.programmover.action.XjTelecomPushListener.pushJwCmsResult(XjTelecomPushListener.java:500)
- locked <0x00000006165e71f0> (a cn.xxxx.programmover.action.XjTelecomPushListener)
at sun.reflect.GeneratedMethodAccessor612.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
ps:有一个工具,可以直观的把锁住的线程展示出来(箭头所指的是标红是死锁线程),而且 可以把等待这把锁的线程给罗列出来,比上面的方法轻松太多
下载地址:https://download.csdn.net/download/soldier_jw/15041230 需要5积分
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/26498.html