JMX之通過RMI方式連線JMX Server
阿新 • • 發佈:2019-02-10
除了可以在HTML中管理MBean之外,我們還可以通過程式來連線JMX管理MBean。這就需要用到了JMX的Connectior,JMX提供了兩種Connector:RMI Connector和JMXMP Connector(JMX message protocol Connector)。下面介紹RMI Connector。
首先還是要建立MBean介面和實現
package com.jmx.client; public interface HelloMBean { public String getName(); public void setName(String name); public void helloWorld(); public void helloWorld(String name); public String getTelephone(); }
package com.jmx.client;
public interface HelloMBean {
public String getName();
public void setName(String name);
public void helloWorld();
public void helloWorld(String name);
public String getTelephone();
}
建立JMXServer和JMXConnectorServer(通過RMI註冊URL提供客戶端連線)
package com.jmx.client; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.MalformedURLException; import java.rmi.registry.LocateRegistry; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import com.sun.jdmk.comm.HtmlAdaptorServer; public class HelloAgent { public static void main(String[] args) throws MalformedObjectNameException, NullPointerException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { //create mbean server MBeanServer server = ManagementFactory.getPlatformMBeanServer(); //create object name ObjectName helloName = new ObjectName("jmxBean:name=hello"); //create mbean and register mbean server.registerMBean(new Hello(), helloName); //create adaptor, adaptor is just a form as show mbean. It has no relation to specific mbean. HtmlAdaptorServer adaptor = new HtmlAdaptorServer(); //create adaptor name ObjectName adaptorName = new ObjectName("jmxAdaptor:name=adaptor,port=5050"); //register adaptor and adaptor name server.registerMBean(adaptor, adaptorName); adaptor.setPort(9999); adaptor.start(); System.out.println("....................server start...................."); //JMXConnectorServer service try { //這句話非常重要,不能缺少!註冊一個埠,繫結url後,客戶端就可以使用rmi通過url方式來連線JMXConnectorServer LocateRegistry.createRegistry(8888); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8888/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server); System.out.println("....................begin rmi start....."); cs.start(); System.out.println("....................rmi start....."); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
這裡的8888(預設為1099)是通訊埠或者查詢埠,服務端在createRegistry時實際上會new ServerSocket(8888),客戶端的socket通過與埠號為8888的服務端埠互聯lookup到server物件。客戶端獲取到的server物件在和服務端的sketon物件進行通訊時實際上也會建立socket連線,資料傳輸時的ServerSocket也需要一個埠(不同於通訊埠),稱之為資料埠。
package com.jmx.client; import java.util.Iterator; import java.util.Set; import javax.management.Attribute; import javax.management.MBeanInfo; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import com.jmx.demo.HelloMBean; public class Client { public static void main(String[] args) throws Exception { //connect JMX JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8888/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url,null); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); ObjectName mbeanName = new ObjectName("jmxBean:name=hello"); //print domains System.out.println("Domains:---------------"); String domains[] = mbsc.getDomains(); for (int i = 0; i < domains.length; i++) { System.out.println("\tDomain[" + i +"] = " + domains[i]); } //MBean count System.out.println("MBean count = " + mbsc.getMBeanCount()); //process attribute mbsc.setAttribute(mbeanName, new Attribute("Name", "new value"));//set value System.out.println("Name = " + mbsc.getAttribute(mbeanName, "Name"));//get value //invoke via proxy HelloMBean proxy = (HelloMBean) MBeanServerInvocationHandler.newProxyInstance(mbsc, mbeanName, HelloMBean.class, false); proxy.helloWorld(); proxy.helloWorld("I'll connect to JMX Server via client."); //invoke via rmi mbsc.invoke(mbeanName, "helloWorld", null, null); mbsc.invoke(mbeanName, "helloWorld", new Object[] { "I'll connect to JMX Server via client2." }, new String[] { String.class.getName() }); //get mbean information MBeanInfo info = mbsc.getMBeanInfo(mbeanName); System.out.println("Hello Class:" + info.getClassName()); System.out.println("Hello Attriber:" + info.getAttributes()[0].getName()); System.out.println("Hello Operation:" + info.getOperations()[0].getName()); //ObjectName of MBean System.out.println("all ObjectName:---------------"); Set set = mbsc.queryMBeans(null, null); for (Iterator it = set.iterator(); it.hasNext();) { ObjectInstance oi = (ObjectInstance)it.next(); System.out.println("\t" + oi.getObjectName()); } jmxc.close(); } }