k8s下服务做threaddump和heapdump操作过程
1. #查询节点的资源使用情况
kubectl -n kjhs-yonyou top nodes
2.#查询每个服务的资源使用情况
kubectl -n kjhs-yonyou top pod
3.#做theaddump和heapdump文件
#找一个内存使用最大的服务,进入容器中做dump文件 kubectl -n kjhs-yonyou exec -it f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd sh (f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd为服务节点名称)
#进入容器之后先检查下是否有jstack和jmap命令,如果是oracle jdk就会有这两个命令;如果不存在就把jdk拷贝到容器中;
jstack -help
jmap -help
#查看对应服务的java进程
ps -ef|grep java
#做threaddump文件操作,建议做3次
jstack 1 > /home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-`date +%Y%m%d%H%M%S`.txt
#做heapdump文件,建议正常情况做一次,发生full gc做一次
jmap -dump:format=b,file=/home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-heapdump-`date +%Y%m%d%H%M%S`.hprof 1
#压缩heapdump文件
gzip f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-heapdump-20230524103142.hprof
#退出容器
exit
4.#把上面做的四个文件拷贝出来(从容器中拷贝到master服务器中)
kubectl cp -n kjhs-yonyou f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-t8tsv:/home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-heapdump-20230524141659.hprof.gz /root/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-heapdump-20230524141659.hprof.gz
kubectl cp -n kjhs-yonyou f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-t8tsv:/home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141636.txt /root/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141636.txt
kubectl cp -n kjhs-yonyou f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-t8tsv:/home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141643.txt /root/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141643.txt
kubectl cp -n kjhs-yonyou f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-t8tsv:/home/admin/app/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141649.txt /root/f9667046-kjhs-yonyou-agla-cwy2-blue-b455b8d56-gs6hd-threaddump-20230524141649.txt
5.#把这四个文件从服务器拿下来,对这四个文件进行分析
#jca分析threaddump
在IBM Thread and Monitor Dump Analyzer for Java工具中,请求线程可分为以下几种状态:
1.死锁,Deadlock(重点关注)
2.执行中,Runnable(重点关注)
3.等待资源,Waiting on condition(重点关注)
4.等待监控器检查资源,Waiting on monitor
5.暂停,Suspended
6.对象等待中,Object.wait()
7.阻塞,Blocked(重点关注)
8.停止,Parked
Deadlock:死锁线程:一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:等待资源,如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取,又或者正在等待其他线程的执行等。
Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管。
#右键txt文件-->Thread Detail
这里基本就显示了各个线程状态分析情况。一般重点查看“等待资源Waiting on condition”、“wait()”、“阻塞Blocked”。这些是引起CPU高,可能是线程执行有死循环。
New:当线程对象创建时存在的状态,此时线程不可能执行;
Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就执行;
Running:线程正在执行:
Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;
Timed_Waiting:执行Thread.sleep()、thread.join()或obj.wait()等就会进该状态,与Waiting的区别在于Timed_Vaiting的等待有时间限制;
Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;
Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束其次,对于jstack日志,我们要着重关注如下关键信息
Deadlock:表示有死锁
Vaiting on condition等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待
Blocked:阻塞
Waiting on monitor entry:在等待获取锁
in Object.wait0:获取锁后又执行obj.wait()放弃锁