通過java程式碼獲取jvm資訊和系統資訊
阿新 • • 發佈:2019-01-02
轉載自LOC_Thomas的部落格
前言
隨著微服務的概念逐漸流行,監控成了必不可少的模組,本篇文章主要介紹一下如何通過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();
這樣就可以輕鬆獲得系統各種引數了