前两天有朋友想了解一下排查问题的时候的技巧,我也是在网上和在工作中看见大神们操作偷学的。服务器上出问题。出现问题的时候,该怎么排查呢?
毫无疑问思路肯定是 Cpu,内存,磁盘,网络,今天的例子就只到了cpu。不过导致这些问题的绝大多数情况都是代码,所以找出来的目的是为了优化代码。
首先上去一个命令肯定是jps(你是环境中的java来跑的情况下) ,看看跑了那些进程,然后就是top了,找到最高使用率的cpu。写了个测试代码
/**
* @author 铁拳阿牛
* @createTime 2018/2/28 下午6:31
**/
public class Test {
public static void main(String[] args) {
Object o = new Object();
for(int i =0 ;i < 100000; i++){
try{
if(i== 1000){
i = 0;
System.out.println(i); //反复打应0
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
然后top 命令下看到cpu 100%(Cpu 可以超过100%我这里只有一个main线程,所以最多跑在一个核心上。这个值是多核心的累加值),记住这个线程 PID。
![](https://img.haomeiwen.com/i6165463/f022a214cc5a196b.png)
然后输入下一个命令 top -Hp PID (上图是25882)然后出现下图。可以很明确的知道,有一个线程跑在这里使用了非常高的Cpu.
![](https://img.haomeiwen.com/i6165463/a565c60b9258572c.png)
接下来你需要去查看线程栈看看,到底是为什么cpu这么高。
你我喜欢 jstack PID > PID_stack.txt 这样来看。(要还是快速排查的时候还是 jstack PID | grep -A (16进制的PID)),然后打印出来查看栈,可以看到
![](https://img.haomeiwen.com/i6165463/ef7148d3d01a7ac8.png)
//Test.main(Test.java:9) 然后去看看着个代码干了啥。
"main" #1 prio=5 os_prio=0 tid=0x00007f9b24009000 nid=0x651b runnable [0x00007f9b28ec5000]
java.lang.Thread.State: RUNNABLE
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
- locked <0x00000000c441e470> (a java.io.BufferedOutputStream)
at java.io.PrintStream.write(PrintStream.java:482)
- locked <0x00000000c4408f30> (a java.io.PrintStream)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
- locked <0x00000000c4408ee8> (a java.io.OutputStreamWriter)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.newLine(PrintStream.java:546)
- eliminated <0x00000000c4408f30> (a java.io.PrintStream)
at java.io.PrintStream.println(PrintStream.java:737)
- locked <0x00000000c4408f30> (a java.io.PrintStream)
at Test.main(Test.java:9)
这样初级问题就很容易定位出来了。
如果你的 线程id在最下面,比如这样:
"VM Thread" os_prio=0 tid=0x00007f9b24077000 nid=0x6520 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f9b2401e000 nid=0x651c runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f9b24020000 nid=0x651d runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f9b24021800 nid=0x651e runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f9b24023800 nid=0x651f runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f9b240cc800 nid=0x6528 waiting on condition
JNI global references: 9
这样就需要别的命令排查了,你可以去看看你假笨的文章或者给我留言,有空写一个。
下面是广告可以关了,关注你假笨的,近期有新玩意哦。
关注阿牛的公众号,从小菜比到老菜比
你假笨
网友评论