操作系统层面监控排查
CPU
1、通过top/vmstat找到目标进程的PID
%Cpu(s): 27.0 us, 9.4 sy, 0.0 ni, 59.0 id, 0.0 wa, 0.0 hi, 4.6 si, 0.0 st
KiB Mem : 7992404 total, 1195504 free, 4612256 used, 2184644 buff/cache
KiB Swap: 8388604 total, 8062456 free, 326148 used. 2837872 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
117466 cpicapp 20 0 8131068 3.064g 18420 S 147.7 40.2 15:28.31 java
100145 cpicapp 20 0 5022008 1.054g 8748 S 6.3 13.8 4404:40 java
2、查看目标进程的CPU消耗命令:
pidstat -p PID -u 1 3
-
-p用于指定进程PID
-
-u对CPU的监控
-
1 3 表述每秒采集一次,合计采集三次
[XXXXXXX@Cloud System!! DT~]$pidstat -p 117466 -u 1 3
3、进一步监控目标进程的线程命令 :
pidstat -p PID 1 3 -u -t
[XXXXXXX@Cloud System!! DT~]$pidstat -p 117466 1 3 -u -t
Linux 3.10.0-862.3.2.el7.x86_64 (xncscbzcapp-c1e0p) 02/22/2021 _x86_64_ (4 CPU)
11:10:05 AM UID TGID TID %usr %system %guest %CPU CPU Command
11:10:06 AM 1050 117466 - 100.00 47.52 0.00 100.00 1 java
11:10:06 AM 1050 - 117466 0.00 0.00 0.00 0.00 1 |__java
11:10:06 AM 1050 - 117470 0.00 0.00 0.00 0.00 3 |__java
11:10:06 AM 1050 - 117471 0.00 0.00 0.00 0.00 0 |__java
11:10:06 AM 1050 - 117472 0.00 0.00 0.00 0.00 2 |__java
11:10:06 AM 1050 - 117473 0.00 0.00 0.00 0.00 3 |__java
11:10:06 AM 1050 - 117474 0.00 0.00 0.00 0.00 0 |__java
线程省略...
11:10:06 AM 1050 - 117555 6.93 1.98 0.00 8.91 0 |__java
11:10:06 AM 1050 - 117556 6.93 1.98 0.00 8.91 0 |__java
11:10:06 AM 1050 - 117557 4.95 1.98 0.00 6.93 1 |__java
11:10:06 AM 1050 - 117558 6.93 0.99 0.00 7.92 3 |__java
11:10:06 AM 1050 - 117568 0.00 0.00 0.00 0.00 2 |__java
11:10:06 AM 1050 - 117569 4.95 3.96 0.00 8.91 2 |__java
11:10:06 AM 1050 - 118167 5.94 0.99 0.00 6.93 1 |__java
11:10:06 AM 1050 - 118168 5.94 1.98 0.00 7.92 1 |__java
11:10:06 AM 1050 - 118169 4.95 0.99 0.00 5.94 2 |__java
11:10:06 AM 1050 - 118170 4.95 3.96 0.00 8.91 1 |__java
11:10:06 AM 1050 - 118171 4.95 2.97 0.00 7.92 0 |__java
11:10:06 AM 1050 - 118172 4.95 4.95 0.00 9.90 3 |__java
11:10:06 AM 1050 - 118173 3.96 3.96 0.00 7.92 0 |__java
11:10:06 AM 1050 - 118174 3.96 2.97 0.00 6.93 3 |__java
11:10:06 AM 1050 - 118175 4.95 3.96 0.00 8.91 0 |__java
11:10:06 AM 1050 - 118176 4.95 2.97 0.00 7.92 1 |__java
4、获得到高消耗线程ID之后执行 :
jstack -l PID >/cpic/thread_cpu.txt
然后查看thread.txt找到对应的线程ID分析即可,文件中的线程ID是十六进制的,使用时注意。
Full thread dump OpenJDK 64-Bit Server VM (17.920-b00 mixed mode):
"Attach Listener" #38 daemon prio=9 os_prio=0 tid=0x00007fd124004800 nid=0x1e84d waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"gatling-http-3-6" #37 prio=5 os_prio=0 tid=0x00007fd0f006f000 nid=0x1cda0 runnable [0x00007fd0e8198000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000006f9d48dc8> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x00000006f9d49ec8> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000006f9d49df0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:757)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:412)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
线程省略...
"gatling-http-3-8" #36 prio=5 os_prio=0 tid=0x00007fd0f4511800 nid=0x1cd9f runnable [0x00007fd0e8299000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000006f9d354a0> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x00000006f9d365a0> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000006f9d364c8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:757)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:412)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
内存
示例略,参考CPU部分
1、通过top/vmstat找到目标进程的PID ,查看目标进程的内存消耗
2、通过PID查看进程中线程内存消耗
3、pidstat -r -p PID 1 5
4、jstack -l PID >/cpic/thread_memory.txt
5、查看thread.txt找到对应的线程ID分析即可
IO
示例略,参考CPU部分
1、通过PID查看进程中线程IO消耗
2、pidstat -p PID -d -t 1 3
3、jstack -l PID >/cpic/thread_memory.txt
4、查看thread.txt找到对应的线程ID分析即可
网络
查看网络状态:
- netstat -an
查看8080端口连接状况:
- netstat -an | grep 80
统计80端口连接数:
- netst -nat | grep -i "80" | wc -l
统计httpd协议连接数:
- ps -ef | grep httpd | wc -l
统计已连接上的,状态为"establish":
- netstat -na | grep ESTABLISHED | wc -l
JVM层面监控排查
jstat
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
option值:
- -class 显示Classloder的相关信息
- -compiler 显示JIT编译的相关信息 -gc 显示与GC相关的堆信息
- -gccapacity 显示各个代的容量及使用情况
- -gccause 显示垃圾回收相关信息(同-gcutil),同时显示最后一次或者当前正在发生的垃圾回收的诱发原因
- -gcnew 显示新生代的相关信息
- -gcnewcapacity 显示新生代大小与使用情况
- -gcold 显示老年代和永久代的信息
- -gcoldcapacity 显示老生代大小
- -gcpermcapacity 显示永久代的大小
- -gcutil 显示垃圾回收信息
- -printcompliation 输出JIT编译的方法信息
示例:
jstat -gc PID 1000(每1000毫秒输出一次) 1000(一共输出1000次)
jmap
- jmap -histo >filename.log java对象统计信息
- jmap -dump:live,format=b,file=filename.bin 堆快照
- jmap -permstat 查看系统Classloader的信息
- jmap -finalizerinfo 查看系统finalzer队列中的对象
jstack
查看高消耗线程的另一种方式 :
- top查看消耗最高的JAVA进程
- 使用top -Hp 来看这个进程里所有线程的cpu消耗情况
- 使用printf "%x\n" 将进程号转换成16进制进程号
- 使用jstack 查看线程栈,通过16进制进程号查找消耗高的线程
线程dump文件里,值得关注的线程状态有:
- 死锁,Deadlock(重点关注)
- 执行中,Runnable
- 等待资源,Waiting on condition(重点关注)
- 等待获取监视器,Waiting on monitor entry(重点关注)
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 阻塞,Blocked(重点关注)
- 停止,Parked
jcmd
- jcmd GC.class_histogram 类的统计信息
- jcmd GC.heap_dump filename.dump 导出堆信息
- jcmd VM.sysytem_properties 获得系统的Properties内容
- jcmd VM.flags 获得启动参数
- jcmd PerfCounter.print 获得所有的PerData数据
JVM可视化分析工具
JVM参数设置优化
一款开源的在线JVM参数设置调优工具:
JVM-GC在线日志分析
线程快照在线分析
堆快照分析
堆快照在线分析
Visual VM
JDK自带的jvisualvm.exe
MAT(MemoryAnalyzer)
下载地址:www.eclipse.org/mat/downloa…