最近接触jmx,查了很多资料,资料是很全,下面总结了本地操作jmx,远程发布、远程访问JMX相关示例,希望能帮到你。
转贴请表明原地址:
http://skyteam.iteye.com/blog/1893302
JDK中对每个方法介绍很是详细,所以查看jdk 文档会有很大的惊喜。
在线JDK连接:
http://www.ostools.net/apidocs/apidoc?api=jdk-zh
----------------------本地操作JMX----------------------------------
获取本地MBeanServerConnection
private MBeanServerConnection getServerConnection() throws IOException,
NotBoundException {
Registry registry = LocateRegistry.getRegistry();
RMIServer stub = null;
JMXConnector jmxc = null;
if (stub == null) {
//registry_name 注册访问连接的名字如service:jmx:rmi:///jndi/rmi://127.0.0.1:8888/jcfJmxConnector
stub = (RMIServer) registry.lookup(REGISTRY_NAME);//jcfJmxConnector
}
jmxc = new RMIConnector(stub, null);
jmxc.connect();
return jmxc.getMBeanServerConnection();
}
获得MBean:
private Set<ObjectInstance> findServer()
throws MalformedObjectNameException, NullPointerException {
MBeanServer server = MBeanServerFactory.findMBeanServer(null).get(0);
return server.queryMBeans(new ObjectName([color=red]
"jcf.mbeans:name=*,type=NewServerController"[/color]), null);
}
****需要注意的是queryMBeans支持模糊查询
循环调用
Set<ObjectInstance> mbeans = findServer();
for (Iterator<ObjectInstance> it = mbeans.iterator();it.hasNext();) {
ObjectInstance oi = it.next();
mbsc.invoke(oi.getObjectName(), "start", null, null);
}
获取当前环境(karaf)JMX,将自己ObjectName注册进去
private void startJmxConnServer() throws Exception {
try {
ArrayList<MBeanServer> servers = MBeanServerFactory
.findMBeanServer(null);
System.out.println(servers.size());
MBeanServer mbs = (MBeanServer) servers.get(0);
ObjectName objName = new ObjectName(
"ManagementJmxServer:name=Management");
mbs.registerMBean(new Management(), objName);
} catch (MalformedObjectNameException e) {
throw new Exception(e);
} catch (InstanceAlreadyExistsException e) {
throw new Exception(e);
} catch (MBeanRegistrationException e) {
throw new Exception(e);
} catch (NotCompliantMBeanException e) {
throw new Exception(e);
} catch (Exception e) {
throw new Exception(e);
}
}
------------------------------远程JMX------------------------------------
代码注册:
MBeanServer server = MBeanServerFactory.createMBeanServer();
server.registerMBean(new Management(), new ObjectName("com.travelsky.jcf.management:type=Management"));
JMXServiceURL url = new JMXServiceURL("rmi", "127.0.0.1", 9589,
"/jndi/rmi://localhost:" + 1099 + "/management");
// 调用方法,初始化
Map<String, String[]> environment = new HashMap<String, String[]>();
String[] credentials = new String[] { "karaf", "karaf" };
environment.put("jmx.remote.credentials", credentials);
JMXConnectorServer jmxServer = JMXConnectorServerFactory
.newJMXConnectorServer(url, environment , server);
System.out.println(url);
// 在RMI上注册
LocateRegistry.createRegistry(1099);
jmxServer.start();
----
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// Construct the ObjectName for the MBean we will register
ObjectName name = new ObjectName("com.travelsky.jcf.control:type=NewServerController");
// Create the Hello World MBean
NewServerController mbean = new NewServerController();
// Register the Hello World MBean
mbs.registerMBean(mbean, name);
-----
spring 文件注册
<bean id="jcfServerMBean" class="com.travelsky.jcf.NewServerController" init-method="init"></bean>
<!-- <context:component-scan base-package="com.travelsky.jcf" /> -->
<context:mbean-export default-domain="jcf.mbeans" />
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true"/>
</bean>
<bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean" destroy-method="destroy">
<property name="port" value="${jcf.jmx.rmi.port}" />
</bean>
<bean id="jcfJmxServer" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="rmiRegistry">
<property name="objectName" value="connector:name=rmi" />
<property name="serviceUrl" value="service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:${jcf.jmx.rmi.port}/jcfJmxConnector" />
<property name="server" ref="mbeanServer" />
<property name="environment">
<!-- the following is only valid when the sun jmx implementation is used -->
<!-- <map>
<entry key="jmx.remote.x.password.file" value="${user.home}/.secure/jmxremote.password" />
<entry key="jmx.remote.x.access.file" value="${user.home}/.secure/jmxremote.access" />
</map> -->
<props>
<prop key="java.naming.security.principal">${jcf.jmx.rmi.username}</prop>
<prop key="java.naming.security.credentials">${jcf.jmx.rmi.password}</prop>
</props>
</property>
</bean>
<bean id="clientConnector" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean" depends-on="jcfJmxServer">
<property name="serviceUrl" value="service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:${jcf.jmx.rmi.port}/jcfJmxConnector" />
<property name="environment">
<map>
<entry key="jmx.remote.credentials">
<bean class=" org.springframework.util.StringUtils" factory-method="commaDelimitedListToStringArray">
<constructor-arg value="${jcf.jmx.rmi.username},${jcf.jmx.rmi.password}" />
</bean>
</entry>
</map>
</property>
</bean>
访问远程JMX
MBeanServerConnection mbeanServerConnection = null;
JMXConnector jmxConnector = null;
JMXServiceURL serviceURL = new JMXServiceURL(URL);
Map<String, String[]> environment = new HashMap<String, String[]>();
String[] credentials = new String[] { USERNAME, PASSWORD };
environment.put("jmx.remote.credentials", credentials);
jmxConnector = JMXConnectorFactory.connect(serviceURL, environment);
mbeanServerConnection = jmxConnector.getMBeanServerConnection();
ObjectName nodeObjName = new ObjectName(
"jcf.mbeans:name=jcfServerMBean,type=NewServerController");
System.out.println(mbeanServerConnection.invoke(nodeObjName, "getRepository", new Object[] { "String1" };new String[] { String.class.getName() }));
package test;
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;
public class Client {
public static void main(String[] args) throws Exception {
JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://localhost:9999/server");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("chengang:name=HelloWorld");
// 把所有Domain都打印出来
System.out.println("Domains:---------------");
String domains[] = mbsc.getDomains();
for (int i = 0; i < domains.length; i++) {
System.out.println("\tDomain[" + i + "] = " + domains[i]);
}
// MBean的总数
System.out.println("MBean count = " + mbsc.getMBeanCount());
// 对name属性的操作(属性名的第一个字母要大写)
mbsc.setAttribute(mbeanName, new Attribute("Name", "Chen.Gang"));// 设值
System.out.println("Name = " + mbsc.getAttribute(mbeanName, "Name"));// 取值
// 得到proxy代理后直接调用的方式
HelloMBean proxy = (HelloMBean) MBeanServerInvocationHandler
.newProxyInstance(mbsc, mbeanName, HelloMBean.class, false);
proxy.printHello();
proxy.printHello("陈刚");
// 远程调用的方式
mbsc.invoke(mbeanName, "printHello", null, null);
mbsc.invoke(mbeanName, "printHello", new Object[] { "子在川上曰" },
new String[] { String.class.getName() });
// 得mbean的信息
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());
// 得到所有的MBean的ObjectName
System.out.println("all ObjectName:---------------");
Set<ObjectInstance> set = mbsc.queryMBeans(null, null);
for (Iterator<ObjectInstance> it = set.iterator(); it.hasNext();) {
ObjectInstance oi = (ObjectInstance) it.next();
System.out.println("\t" + oi.getObjectName());
}
}
// 注销
// mbsc.unregisterMBean(mbeanName);
// 关闭MBeanServer连接jmxc.close();
}