前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM Monitor

JVM Monitor

作者头像
itliusir
发布2019-12-11 12:11:13
8380
发布2019-12-11 12:11:13
举报
文章被收录于专栏:刘君君

摘要: jvm monitor

正文:

JVM 监控

基于 jstack 监控定位

查看CPU负载

  • 系统负载/ CPU负载 - 是Linux系统中CPU过度使用率或利用率不足的度量; CPU正在执行或处于等待状态的进程数。
  • 负载平均值 - 是在给定的1,5和15分钟时间段内计算的平均系统负载。
  • top 命令 (定位到我们cpu高的进程)
代码语言:javascript
复制
$ top
top - 16:40:59 up 388 days,  1:04,  1 user,  load average: 0.00, 0.01, 0.05
Tasks:  75 total,   1 running,  72 sleeping,   0 stopped,   2 zombie
%Cpu(s):  0.7 us,  0.3 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1883492 total,   247312 free,   473204 used,  1162976 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1188144 avail Mem 

$ uptime
 16:42:36 up 388 days,  1:06,  1 user,  load average: 0.00, 0.01, 0.05

其中 load average 代表的是cpu的平均负载,三个数字分别代表1分钟、5分钟、15分钟内cpu的平均负载。 负荷的大小跟cpu个数以及当前负荷有关系,例如1h 处理器,负载为5 则大概表面有1成的在running 4成的在等待,也就意味着此时可能服务器已经无法处理新的请求了,系统也就凉咯 查看cpu个数

代码语言:javascript
复制
$ cat /proc/cpuinfo | grep "cpu cores" 

定位具体线程

  • jstack 命令 例如我们由top定位到了某个异常的进程,拿到了pid,为9048 接下来我们使用 jstack 命令导出 9048 进程中线程栈的信息
代码语言:javascript
复制
$ jstack 9048 > 9048.txt
$ top -p 9048 -H # 拿到所有线程的cpu信息,定位具体线程pid
9243 root      20   0 2498028  59096   7008 S  91.0  3.1   0:00.00 java           
9244 root      20   0 2498028  59096   7008 S  99.0  3.1   0:00.32 java
# 定位到线程pid为 9243 9244的cpu占用高
$ printf "%x" 9243 # 转为16进制--> 2353
$ printf "%x" 9244 # 转为16进制--> 2354
# 在9048.txt 查找nid为 0x2353 和 0x2354的线程栈信息,最后发现是nio的WindowsSelectorImpl导致的
$ cat 9048.txt

"http-nio-8499-ClientPoller-0" #27 daemon prio=5 os_prio=0 tid=0x4e69c800 nid=0x2353 runnable [0x5108f000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.WindowsSelectorImpl.resetWakeupSocket0(Native Method)
	at sun.nio.ch.WindowsSelectorImpl.resetWakeupSocket(Unknown Source)
	- locked <0x257756d8> (a java.lang.Object)
	at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
	- locked <0x257756b8> (a sun.nio.ch.Util$2)
	- locked <0x257756a8> (a java.util.Collections$UnmodifiableSet)
	- locked <0x2575d518> (a sun.nio.ch.WindowsSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(Unknown Source)
	at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:744)
	at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
	- None 

基于 JvisualVM 的可视化监控

本地监控

打开 JDK 安装目录 bin 文件夹下的 jvisualvm.exe ,在左侧的本地下可以看到正常运行的java 应用,除了正常的类似命令行界面化的操作外,我们可以安装别的好用的插件

  1. 工具–插件–设置–编辑 将URL修改为 https://visualvm.github.io/pluginscenters.html 中对应的JDK版本下的地址,如JDK 8 Update 131 - 192 https://visualvm.github.io/uc/8u131/updates.xml.gz
  2. 切换TAB至可用插件,在其列表中选中 Visual GC 插件安装后重启jvisualvm.exe 即可看到多出的 Visual GC Tab

远程监控

监控远程Tomcat
  • 修改 Catalina.sh 文件
代码语言:javascript
复制
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=xx -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferlPv4Stack=true -Djava.rmi.server.hostname=xx.xx.xx.xx" 
监控远程普通java进程
  • 添加启动参数
代码语言:javascript
复制
 nohup java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=xx -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferlPv4Stack=true -Djava.rmi.server.hostname=xx.xx.xx.xx -jar xx.jar & 

JvisualVM 参考链接

基于Btrace的监控调试

Btrace可用动态的向目标应用程序的字节码注入追踪代码

下载安装

  • 下载安装包 https://github.com/btraceio/btrace 下载realse版本我这里是 v1.3.11.3
  • 解压并配置环境变量 新增环境变量 BTRACE_HOME ,Path 中追加 %BTRACE_HOME%\bin

运行方式

  • JVisualVM 中添加Btrace插件,添加 classpath
  • 使用命令行 btrace <pid> <trace_script>

使用方法

Demo

这里举在JVisualVM 中使用的例子,安装完Btrace插件后,对其中的 java 应用列表右键打开Trace application,例如对某个应用的某个查询方法的脚本如下:

代码语言:javascript
复制
import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

@BTrace
public class PrintArgDemo {
	
	@OnMethod(
		clazz="com.clamc.climb.admin.web.UserController",
		method="query",
		location=@Location(Kind.ENTRY)
	)
	public static void queryTest(@ProbeClassName String className, @ProbeMethodName String methodName, AnyType[] args) {
		BTraceUtils.printArray(args);
		BTraceUtils.println(className + " " + methodName);
		BTraceUtils.println();
	}
}

勾上 Output Class-Path (Class-Path 可以用来增加第三方jar包),点击 Start 即可等待执行到 query 方法后的打印输出

Doc
  • 普通方法 @OnMethod(clazz=””,method=””)
  • 构造方法 @OnMethod(clazz=””,method=”“)
  • 重载方法通过参数区分
  • Kind 拦截时机
    • Kind.ENTRY 入口,默认值
    • Kind.RETURN 返回
    • Kind.THROW 异常
    • Kind.Line 行
  • this: 形参+@Self 可以拦截this对象
  • 复杂的参数可以通过反射获取
  • printXxx()

注意事项

  • 默认只能本地运行
  • 生产环境下也可以使用,但是被修改的字节码不会被还原
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文:
  • JVM 监控
    • 基于 jstack 监控定位
      • 查看CPU负载
      • 定位具体线程
    • 基于 JvisualVM 的可视化监控
      • 本地监控
      • 远程监控
    • 基于Btrace的监控调试
      • 下载安装
      • 运行方式
      • 使用方法
      • 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档