之前学了如何创建JMX技术的MBeans和MXBeans,并用JMX代理注册它们。可是,之前所用的都是已经存在的JMX客户端,JConsole。这里将演示如何创建自己的客户端。
一个普通的JMX客户端的例子,Cilent存在于jmx_example.zip中。JMX客户端与同样的MBean和MXbean,JMX 代理交互。由于Client类的大小,它将在块中检查。
导入JMX远程API类
创建从JMX客户端到运行在远程的JMX代理的连接,你需要使用javax.management.remote类。
package com.example;
...
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class Client {
...
这个Client创建JMXConntor实例,还需要一个JMXConnectorFactory和一个JMXServiceURL。
创建通知监听器
JMX客户端需要一个通知处理者,来监听和处理任何通知,这些通知由在JMX代理的MBean服务器上注册的MBeans发送。JMX客户端通知处理者是一个NotificationListener接口的实例,如下所示:
...
public static class ClientListener implements NotificationListener {
public void handleNotification(Notification notification,
Object handback) {
echo("\nReceived notification:");
echo("\tClassName: " + notification.getClass().getName());
echo("\tSource: " + notification.getSource());
echo("\tType: " + notification.getType());
echo("\tMessage: " + notification.getMessage());
if (notification instanceof AttributeChangeNotification) {
AttributeChangeNotification acn =
(AttributeChangeNotification) notification;
echo("\tAttributeName: " + acn.getAttributeName());
echo("\tAttributeType: " + acn.getAttributeType());
echo("\tNewValue: " + acn.getNewValue());
echo("\tOldValue: " + acn.getOldValue());
}
}
}
...
通知监听器确定任何通知的来源,监听器接受和重新获取存在通知中的信息。。稍后根据接受的通知类型随着通知的信息执行不同操作,在这种情况下,当监听器接受到AttributeChangeNotification类型的通知时,t它将获取MBean已经改变的属性的名字和类型,还有老的和新的值,通过调用AttributeChangeNotification的方法getAttributeName,getAttributeType,
getNewValue 和getOldValue.
在后面的代码中创建了新的ClientListener实例:
ClientListener listener = new ClientListener();
创建RMI连接器客户端
Client类创建一个RMI连接器客户端,被配置为连接一个RMI连接器服务,当你开启JMX代理的时候,启动Main。这样将使JMX客户端和JMX代理交互,如果它们运行在同一台机器上。
...
public static void main(String[] args) throws Exception {
echo("\nCreate an RMI connector client and " +
"connect it to the RMI connector server");
JMXServiceURL url =
new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
...
Client 定义了一个JMXServiceURL命名为url,表示了连接器服务的位置。URL允许连接客户端重新获取RMI连接服务的子jmxrmi,来自运行在本地主机端口号为9999的RMI注册表上,并连接RMI连接服务。
随着RMI注册表的定义,连接客户端被创建了。即lmxc,是接口JMXConnector的一个实例,由JMXFactory的connect方法创建,这个方法需要传递一个url和一个空的环境映射做为参数。
连接到远程的MBean服务
随着RMI连接到位,JMX客户端必须连接远程的MBean服务。这样它才可以与注册在远程JMX代理上的不同的MBeans交互。
...
MBeanServerConnection mbsc =
jmxc.getMBeanServerConnection();
...
mbsc是MBeanServerConnection的实例,通过JMXConnector的实例jmxc调用getMBeanServerConnection()方法创建。
连接客户端现在连接到MBean服务器上,由JMX代理创建,能注册MBeans并能执行操作,在两端的连接上。
...
echo("\nDomains:");
String domains[] = mbsc.getDomains();
Arrays.sort(domains);
for (String domain : domains) {
echo("\tDomain = " + domain);
}
...
echo("\nMBeanServer default domain = " + mbsc.getDefaultDomain());
echo("\nMBean count = " + mbsc.getMBeanCount());
echo("\nQuery MBeanServer MBeans:");
Set<ObjectName> names =
new TreeSet<ObjectName>(mbsc.queryNames(null, null));
for (ObjectName name : names) {
echo("\tObjectName = " + name);
}
...
客户端调用了MBeanServerConnection类的不同方法来获取领域,在领域中不同的Mbeans在操作注册在MBean服务上的大量MBeans和它发现的每个Mbean的对象名。
Performing Operations on Remote MBeans via Proxies
通过代理在远程Mbeans上执行操作
客户端访问MBean服务上的Hello Mbean,通过Mbean服务连接,由一个Mbean代理创建。MBean代理位于客户端,模拟了远程MBean。
...
ObjectName mbeanName = new ObjectName("com.example:type=Hello");
HelloMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName,
HelloMBean.class, true);
echo("\nAdd notification listener...");
mbsc.addNotificationListener(mbeanName, listener, null, null);
echo("\nCacheSize = " + mbeanProxy.getCacheSize());
mbeanProxy.setCacheSize(150);
echo("\nWaiting for notification...");
sleep(2000);
echo("\nCacheSize = " + mbeanProxy.getCacheSize());
echo("\nInvoke sayHello() in Hello MBean...");
mbeanProxy.sayHello();
echo("\nInvoke add(2, 3) in Hello MBean...");
echo("\nadd(2, 3) = " + mbeanProxy.add(2, 3));
waitForEnterPressed();
...
MBean代理允许你访问一个MBean,通过一个Java接口,允许你调用代理而不是写长长的代码访问一个远程MBean。Hello的MBean代理由调用Javax.management.JMX类的newMBeanProxy()方法在这里创建,传递了一下参数,MBean的MBeanServerConnection,对象名,MBean接口的类名和布尔值true,表示这个代理必须与NotificationBroadcast类的行为一样。JMX客户端可以现在可以执行由Hello定义的操作,就好像是在本地注册的MBean的操作一样。JMX客户端也增加了一个配置监听器并改变了MBean的CacheSize属性,使他发送一个通知。
Performing Operations on Remote MXBeans via Proxies
通过代理在远程Mbeans上执行操作你可以用创建MBean代理的方式创建MBeans代理
...
ObjectName mxbeanName = new ObjectName ("com.example:type=QueueSampler");
QueueSamplerMXBean mxbeanProxy = JMX.newMXBeanProxy(mbsc,
mxbeanName, QueueSamplerMXBean.class);
QueueSample queue1 = mxbeanProxy.getQueueSample();
echo("\nQueueSample.Date = " + queue1.getDate());
echo("QueueSample.Head = " + queue1.getHead());
echo("QueueSample.Size = " + queue1.getSize());
echo("\nInvoke clearQueue() in QueueSampler MXBean...");
mxbeanProxy.clearQueue();
QueueSample queue2 = mxbeanProxy.getQueueSample();
echo("\nQueueSample.Date = " + queue2.getDate());
echo("QueueSample.Head = " + queue2.getHead());
echo("QueueSample.Size = " + queue2.getSize());
...
如上所示,为创建一个MBean代理,你所需要做的是调用newMBeanProxy实例。MXBean代理mxbeanProxy允许客户端调用QueueSample MXBean的操作就如注册在本地的MXBean的操作。
Closing the Connection
关闭连接
只要JMX客户端获取了它所需的所有信息并执行了远程JMX代理MBean服务上的所有请求的MBeans的操作,连接必须关闭。
jmxc.close();
通过调用JMXConnector.close()关闭。
To Run the Custom JMX Client Example
运行JMX客户端例子这个例子需要JAVA SE6版本。用一个通用JMX客户端Client监控MainJMX代理,按照以下步骤:
如果上一章一样

2099

被折叠的 条评论
为什么被折叠?



