利用JMX統計遠程JAVA進程的CPU和Memory__JAVA

來源:互聯網
上載者:User
從JAVA 5開始,JDK提供了一些JVM檢測的API,這就是有名的java.lang.management 包,包裡提供了許多MXBean的介面類,可以很方便的擷取到JVM的記憶體、GC、線程、鎖、class、甚至作業系統層面的各種資訊,本文就簡單的介紹一種利用JMX對JAVA進程進行CPU、堆記憶體使用量的監控。可能有人會覺得沒必要這樣做,因為用jconsole之類的工具都能做到,而且會比本文的例子更詳細。但是有些時候將console不一定能監控到作為系統服務的java進程,我最近就不得不自己編碼去擷取遠程java進程的監控資料。希望能起到拋磚引玉的作用吧。

      首先,簡要介紹下JMX(Java Management Extensions),即JAVA管理擴充,用來監視和管理JVM以及其啟動並執行作業系統。目前java平台主要提供了下圖所示的9個MXBean, 各個MXBean的作用根據類名大概能猜出幾分,具體可查API。


        java.lang.management包中的mxbean提供了基本的功能,在sum.com.management中對某些功能有所增強,當然我們也可以根據JMX規範提供自己的MXBean。

 

       下面我主要使用java.lang.management.MemoryMXBean和sun.com.management.OperatingSystemMXBean分別對遠程JAVA進行記憶體和cpu的監控。根據需求5秒鐘讀取一次資料,記憶體主要是已使用的Heap Memory,CPU主要就是使用率了。

 

       在使用OperatingSystemMXBean以及MemoryMXBean之前,首先必須得到JMXConnector並建立MBeanServerConnnection,有了這個connection我們就可以利用ManagementFactory建立需要的MXBean了,類依賴圖如下:



        範例程式碼: Java代碼   /*  * host: 遠程機器的ip地址  * port: 遠程java進程啟動並執行jmxremote連接埠  */   JMXServiceURL serviceURL = new JMXServiceURL( host,port );   JMXConnector conn = JMXConnectorFactory.connect(serviceURL);   MBeanServerConnection mbs=conn.getMBeanServerConnection();      //擷取遠程memorymxbean   MemoryMXBean memBean=ManagementFactory.newPlatformMXBeanProxy   (mbs,ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);   //擷取遠程opretingsystemmxbean   com.sun.management.OperatingSystemMXBean opMXbean =    ManagementFactory.newPlatformMXBeanProxy(mbs,                  ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);  

 

       然後,採集memory的資料就比較簡單了,直接調用API擷取: Java代碼   /**    Collect data every 5 seconds      */   try {       TimeUnit.SECONDS.sleep(5);   } catch (InterruptedException e) {       logger.error("InterruptedException occurred while MemoryCollector sleeping...");   }      MemoryUsage heap = memBean   etHeapMemoryUsage();   MemoryUsage nonHeap = memBean   etNonHeapMemoryUsage();   long heapSizeUsed = heap.getUsed();//堆使用的大小   long nonHeapSizeUsed = nonHeap.getUsed();   long heapCommitedSize = heap.getCommitted();   long nonHeapCommitedSize = nonHeap.getCommitted();                     

      採集CPU利用率需要自己計算一下,因為API只提供了擷取cpu的使用時間,我得在兩次系統時間間隔內擷取兩次CPU的使用時間,得到在該時間間隔內cpu使用的時間,相除即得到CPU的使用率,當然誤差肯定存在。 計算cpu使用率代碼           Long start = System.currentTimeMillis();           long startT = opMXbean.getProcessCpuTime();           /**    Collect data every 5 seconds      */           try {               TimeUnit.SECONDS.sleep(5);           } catch (InterruptedException e) {               logger.error("InterruptedException occurred while MemoryCollector sleeping...");           }           Long end = System.currentTimeMillis();           long endT = opMXbean.getProcessCpuTime();   //end - start 即為當前採集的時間單元,單位ms   //endT - startT 為目前時間單元內cpu使用的時間,單位為ns   //所以:double ratio = (entT-startT)/1000000.0/(end-start)/opMXbean.getAvailableProcessors()    

      核心代碼就是這些了,當然,具體使用的話應該用單獨的線程分別取cpu、memory資料,讀取的資料需要寫檔案或者畫圖,監控時間長的話還要定時的將這些資料刷到磁碟檔案或資料庫中,等,這些都是題外話了。這邊我寫到excel中,然後在excel中圖形展示,遠程監控的程式不方便展示,僅僅來監控一段類比cpu正弦曲線的程式,來看看我監控到的資料(圖形)是否和預期一致,並與jconsole採到的有何差異: 被測程式,類比cpu正弦曲線代碼   public class SinCpu {          public static final double TIME = 1000;          /**        * @param args the command line arguments        */       public static void main(String[] args) throws InterruptedException {               new Thread(new SinTask()).start();       }                       static class SinTask implements Runnable{              @Override           public void run() {               double x = 0;               double y = 0;                  while (true) {                   y = (Math.sin(x) + 1) * TIME / 2;                   doSomeSimpleWork(y);                   x += 0.1;                   try {                       Thread.sleep((long) (TIME - y));                   } catch (InterruptedException e) {                       e.printStackTrace();                   }               }           }           private void doSomeSimpleWork(double y) {               long startTime = System.currentTimeMillis();               while ((System.currentTimeMillis() - startTime) < y) {               }           }       }   }  

 

       監控結果基本和預期一樣,CPU資料圖呈現預期的正弦曲線:


        上圖中,第一個圖是從jconsole監控圖中截過來的,而下圖是我利用opMXBean計算獲得,兩個圖基本吻合,資料基本波動在0-25%是因為我測試機器是四核的cpu,兩個映像之間有位移是因為,我手動開啟jconsole沒有我程式監控來的快,所以大概映像平移下基本吻合。

        記憶體的測試應該比CPU還要准一些,這裡就不貼了。Note: 如果監控的程式線程數量很大,cpu會有較明顯誤差,而且採的頻率不夠高的話可能有些點漏采。

 

最後:被測程式必須開放JMXREMOTE連接埠,具體使用參數:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=[開放的連接埠]
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.