用JMX怎樣連線本地JVM上執行的Java程式

帶著紅領巾的雷鋒發表於2015-05-21

enter image description here

    如果有人問你,如何用JMX連線本地JVM上執行的Java程式,你會怎麼回答?

    其實,他只是想開發一個JMX的客戶端來配置一個本地Java程式。這個時候,千萬不要推薦JConsole,因為JConsole是一個通用的JMX客戶端,對主程式的效能存在負面影響。

   在JConsole中,可以選擇PID來連線Java程式。但是在JMX的API中,卻找不到任何方法是使用PID作為引數的。這時候怎麼處理呢?

   使用一些類似下面的程式來連線JMX伺服器,就可實現。不過,需要在執行伺服器時指定以下引數:

-Dcom.sun.management.jmxremote

-Dcom.sun.management.jmxremote.authenticate=false

-Dcom.sun.management.jmxremote.port=1234

-Dcom.sun.management.jmxremote.ssl=false

為了繫結特定地址,還需要在增加下面的VM引數:

-Djava.rmi.server.hostname=A.B.C.D

這樣,你可以像下面的JMX客戶端程式碼一樣連線你的伺服器了:

String host = "localhost"; // or some A.B.C.D

int port = 1234;

String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";

JMXServiceURL serviceUrl = new JMXServiceURL(url);

JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);

try {

MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();

// now query to get the beans or whatever

Set beanSet = mbeanConn.queryNames(null, null);

...

} finally {

jmxConnector.close();

}

當然也可以不使用VM引數,程式碼本身可以通過程式設計在指定埠號釋出,但這肯定就比現在的需求更復雜了。

如果要根據PID來連線,則需要使用Java 6以上的版本:

List vms = VirtualMachine.list();

for (VirtualMachineDescriptor desc : vms) {

VirtualMachine vm;

try {

    vm = VirtualMachine.attach(desc);

} catch (AttachNotSupportedException e) {

    continue;

}

Properties props = vm.getAgentProperties();

String connectorAddress =

    props.getProperty("com.sun.management.jmxremote.localConnectorAddress");

if (connectorAddress == null) {

    continue;

}

JMXServiceURL url = new JMXServiceURL(connectorAddress);

JMXConnector connector = JMXConnectorFactory.connect(url);

try {

    MBeanServerConnection mbeanConn = connector.getMBeanServerConnection();

    Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);

    ...

} finally {

    jmxConnector.close();

}

}

我已釋出過一個新的SimpleJMX包,該包能幫助很簡單的啟動一個JMX服務,並向遠端客戶端傳送beans。

//建立一個新的伺服器並監聽8000埠

JmxServer jmxServer = new JmxServer(8000);

//啟動伺服器

jmxServer.start();

//註冊下面定義的lookupCache物件

jmxServer.register(lookupCache);

jmxServer.register(someOtherObject);

//停止服務

jmxServer.stop();

   該包確實有一個客戶端的介面,但是當前沒有人一種機制是可以通過PID來查詢程式的,只支援主機/埠的組合方式查詢。

推薦學習:Java高階應用視訊教程

文章來源:code

相關文章