前言
随着微服务的概念逐渐流行,监控成了必不可少的模块,本篇文章主要介绍一下如何通过java代码获得一些核心的数据,方便从各个方面对应用进行监控
获取jvm数据
�jvm数据是监控应用很重要的一系列参数,一般本地开发的时候可以通过jconsole来连到对应的进程上面,查看相关指标数据,但是在线上环境就不适合通过jconsole来查看了, 所以我们现在使用通过java代码来获得数据,然后上报出去,然后在外部通过展示。
那么如何通过java代码来得到这些参数呢?
获得jvm的堆内存代码
MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
System.out.println("jvm.heap.init is " + (heapMemoryUsage.getInit()));
System.out.println("jvm.heap.used is " + (heapMemoryUsage.getUsed()));
System.out.println("jvm.heap.committed is " + (heapMemoryUsage.getCommitted()));
System.out.println("jvm.heap.max is " + (heapMemoryUsage.getMax()));
获得jvm的非堆内存代码
MemoryUsage nonHeapMemoryUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
System.out.println("jvm.nonheap.init is " + (nonHeapMemoryUsage.getInit()));
System.out.println("jvm.nonheap.used is " + (nonHeapMemoryUsage.getUsed()));
System.out.println("jvm.nonheap.committed is " + (nonHeapMemoryUsage.getCommitted()));
System.out.println("jvm.nonheap.max is " + (nonHeapMemoryUsage.getMax()));
上面的方法只能得到jvm的堆和非堆的整体数据,一般都知道堆和非堆里面都几个不同的区,用来做不同功能,那么如何得到不同区的数据呢?不多说,上代码
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
final String kind = pool.getType() == MemoryType.HEAP ? "heap" : "nonheap";
final MemoryUsage usage = pool.getUsage();
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".init is " + usage.getInit());
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".used is " + usage.getUsed());
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName()+ ".committed is " + usage.getCommitted());
System.out.println("kind is " + kind + ", pool name is " + pool.getName() + ", jvm." + pool.getName() + ".max is " + usage.getMax());
}
这样就可以得到各种区的具体参数。
获取操作系统参数
上面获得了jvm的参数,但是还是需要监控机器的参数,如果想获得机器的参数,仅仅通过jdk自带的api要获得,难度比较大,所以推荐使用一些开源的jar包。
大家比较熟悉的获得操作系统的jar包是, sigar这个包, 但是我试用了一下, 觉得这个包太难用了。 不是指sigar的api难用,而是他获得系统参数需要一些so文件或者dll文件,如果没有的话,调用sigar的api时候会抛出异常,所以要用起来还要去检查这些文件是否存在, 比较麻烦。
这个时候无意中发现了oshi这个包, 它不需要sigar所需要so或者dll文件, 仅仅需要一个jna的包, 就可以了。所以我在pom.xml里面加上了
<dependency>
<groupId>com.github.dblock</groupId>
<artifactId>oshi-core</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>com.github.dblock</groupId>
<artifactId>oshi-json</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.2.1</version>
</dependency>
然后通过oshi的api
SystemInfo si = new SystemInfo();
XXX xxx = si.getXXX();
这样就可以轻松获得系统各种参数了。