金融风险管理师:JMX IN ACTION---第三章

来源:百度文库 编辑:九乡新闻网 时间:2024/04/27 18:21:57
JMX IN ACTION---第三章
分类:JMX 2011-06-17 22:18 26人阅读评论(0)收藏举报
第三章 构建一个基础程序
本章的目的是为贯穿本书的很多例子打下一个很好的基础程序。当你阅读余下的章节时,大部分的时间会花在开发MBean 上,多数例子会在它所在的章节来执行,用以演示工作代码。所有的例子中,你都需要一个JMX 代理来容纳你的MBean ,为了避免重复的写同样的代理代码,本节将会开发一个用于全书的JMX 代理。另外,随着内容的进一步展开,为了增加其他的服务和工具,还会逐渐的向代理中添加新功能。
代理的范围
在开始写代码之前,你需要明白一点,我们本节构建的代理和第二章的HelloAgent 类将会很相似。事实上,两者之间只有一个主要的不同。但是重要的是,随着书内容的进展,你会按照需要不断的向它里面添加代码。因此,在我们讨论任何新的主题之前,这个代理几乎和HelloAgent 是同样的。
代理类由 jmxbook.ch3.JMXBookAgent 定义,它有两个责任:
§         创建 MBean  server
§         提供链接
就像前一章的HelloAgent , JMXBookAgent 必须有一个MBean server ,另外它也会创建一个HTML 适配器,通过它你可以检查驻留在代理中MBean 以及可以和它们交互。然而,除了HTML 适配器外,将会添加一个RMI 连接器,用于给后面的例子提供以程序的方式和代理来交互的功能。图3.1 说明了代理使用的这两种方式。

JMXBookAgent  in action with the HTML adapter  and RMI  connector
从图上可以看到,你可以通过浏览器和RMI 客户端两种方式和代理交互。本章的后续部分将会创建一个用于创建RMI 客户端的工厂类,其他需要RMI 客户端的例子将会使用这个工厂类来请求一个RMI 客户端.
3.1.1 使用 HTML 适配器
向代理中添加HTML 适配器将会很有用,就像你在第二章看到的那样。它会给你个进入代理的视图,允许你查看驻留在MBean server 中的MBean 列表,并且不仅仅如此,就如你在第二章看到的那样,通过它你还可以操纵MBean 、添加更多的MBean 、移除MBean 等。在后面的例子中,你会主要使用HTML 适配器通过查看和浸入MBean 的属性和操作来测试例子。
3.1.2 使用 RMI 连接器
RMI 连接器和HTML 起同样的作用:允许外边的客户端连接代理并和它交互。我们将使用的RMI 连接器有Sun 的JMX RI 提供。
RMI 连接器有两部分:server 和client 。Server 会驻留在JMX 代理中来提供侵入MBean server 。Client 端驻留在那些想和JMX 代理交互的客户端进程中。RMI client 避免了用户自己写RMI 代码。图3.2 解释了RMI 连接器怎样被用于从远端创建MBean 。

JMXBookAgent  showing the different parts of the RMI  connector  with example createMBean()  method delegation from client to server
以后的例子中,你会使用RMI 连接器和代理通过程序交互。因为HTML 适配器不能和所有的类的工作,所以有时候可能需要通过代码侵入代理。这种情况你就需要使用RMI 客户端。
处于本章的目的,我们不会讨论RMI 连接器API 的特性,我们将只是解释怎么把它加入到代理中以及怎样使用它。

JMXBookAgent 类并不难 ,整个类分为4 个部分:
§         类定义和构造方法
§         添加HTML 适配器
§         添加RMI 连接器
§         添加main() 方法
3.2.1 类定义和构造方法
第一步需要定义类,然后是构造方法,如Listing 3.1 所示:
Listing 3.1 The first part of JMXBookAgent .java
package jmxbook.ch3;
import com.sun.jdmk.comm.*;
import javax.management.*;
public class  JMXBookAgent  {
private MBeanServer  server = null;
public JMXBookAgent (){
System.out.println("/n/tCREATE the MBeanServer .");
server = MBeanServerFactory .createMBeanServer("JMXBookAgent "); #1
startHTMLAdapter() ;                    #2
startRMIConnector() ;                   #2
}
}
( 注解)
( 注解)
此刻需要导入两个包:javax.management.* 和 com.sun.jdmk.comm.* ( 后面你会导入更多的包) 。第二个包包含了HTML adapter   和 the RMI  connector 所需要的类。
构造方法必须初始化它的MBean Server ,使用的域名是“JMXBookAgent ”。然后,调用了两个方法分别开始HTML adapter 和RMI  connector 。下面两节就分别讨论这两个方法的实现。
3.2.2 添加代理连接
为了使代理更有用,我们将添加一个适配器和一个连接器,这样就可以分别通过可视化的方式和编程的方式,来和代理交互了。我们需要HTML 适配器来完成类似第二章的工作:可以简便的查看代理中的内容(MBeans ),如果只是仅仅使用HTML 适配器,就可以注册和接受通知。
但是, 为了学习通知机制  ( 以及后面的例子), 我们需要和代理以程序的方式交互。因此,我们在代理中添加了一个RMI 连接器,它会允许我们使用RMI 客户端或是直接通过代码来连接代理。下面两个小节开始向代理中添加连接。
适配器
在第二章已经看到了添加HTML 适配器的代码,本章这些代码被放在了方法startHTMLAdapter() 中,如Listing 3.2 所示:
Listing 3.2 startHTMLAdapter() method that adds the HTML adapter  to the agent
protected void startHTMLAdapter() {
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
ObjectName  adapterName = null;
try{
adapter.setPort( 9082 );
//create the HTML adapter
adapterName = new ObjectName ("JMXBookAgent :name=html,port=9092" );
server.registerMBean( adapter, adapterName );
adapter.start();
}catch(Exception e) {
ExceptionUtil.printException( e );
System.out.println("Error Starting HTML Adapter for Agent");
}
}
从前面的章节中已经知道HTML 适配器也是MBean ,所以它得像其他的MBean 一样注册在代理中,需要一个ObjectName 实例,在它中可以提供代理的域以及其他的描述信息。一旦在MBean server 中注册了,就可以调用start() 方法运行它了,中间发生任何错误都会打印在代理控制台的输出。
注意catch 块中的ExceptionUtil # printException 方法,本章结束的时候就会了解它了。
RMI   连接器
现在为止,关于HTML 适配器的创建和注册你已经看到两次了,但是还没有看到RMI 连接器代码的影子呢(注意,本章我们不会深入连接器,只是通过一个例子说明怎么使用。后面的章节会使用连接器添加和操作代理中的MBean 。想了解连接器的细节,可以提前跳到第九章)
Listing 3.3 显示了startRMIConnector()   方法 ,它创建然后启动了RMI 连接器:
Listing 3.3 startRMIConnector() method that adds the RMI  connector  server to the agent
protected void startRMIConnector() {
RmiConnectorServer  connector = new RmiConnectorServer();
ObjectName  connectorName = null;
try{
connector.setPort( 2099 );
connectorName = new ObjectName ("JMXBookAgent :name=RMIConnector");
server.registerMBean(connector, connectorName );
connector.start();
}catch(Exception e) {
ExceptionUtil.printException( e );
}
}
这个方法的实现和startHTMLAdapter() 很像,首先创建一个RmiConnectorServer 实例(它是连接器MBean ),然后使用一个新的ObjectName 实例注册它,之后调用它的start() 启动它,开始准备接受请求。后面我们创建一个RMI 客户端工厂用于为RMI 连接器创建客户端。
3.2.3 完成 main() 方法
Listing 3.4 展示了main 方法,它简单的创建了一个代理实例和打印了一些信息
Listing 3.4 The main() method of the JMXBookAgent  class
public static void main(String[] args){
System.out.println("/n~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("/n>>> START of JMXBook Agent");
System.out.println("/n>>> CREATE the agent ...");
JMXBookAgent  agent  = new JMXBookAgent();
System.out.println("/nAgent is Ready for Service.../n");
}
随着mian() 方法的完成,我们已经完成了代理的代码部分。刚才提到,当使用RMI 连接器和代理交互时需要提供创建一种RMI 客户端的方式。下节提供一个工具类RMIClientFactory 来解决这个问题。

RMIClientFactory   类是提供一个便捷的方式来生成RMI 客户端用于连接JMX 代理。当前,工厂类使用所有的默认值来返回一个客户端,在第九章会看到怎样改变默认值。Listing 3.5 显示了这个类:
Listing 3.5 RMIClientFactory .java
package jmxbook.ch3;
import javax.management.*;
import com.sun.jdmk.comm.*;
public class  RMIClientFactory {
public static RmiConnectorClient getClient(){
RmiConnectorClient client = new RmiConnectorClient();
RmiConnectorAddress address = new RmiConnectorAddress();
address.setPort( 2099 );
System.out.println("/t/tTYPE/t= " + address.getConnectorType ());
System.out.println("/t/tPORT/t= "   + address.getPort());
System.out.println("/t/tHOST/t= "   + address.getHost());
System.out.println("/t/tSERVER/t= " + address.getName());
try{
client.connect( address );
}catch( Exception e ) {
ExceptionUtil.printException( e );
}
return client;
}
}
要得到一个客户端,调用getClient() 方法新建一个RmiConnectorClient 对象并使用RmiConnectorAddress 对象初始化它。这个方法中RMI 服务器的端口是2099.

ExceptionUtil 是一个简单的工具类,用来打印MBeanException 的整个异常栈。MBeanException 包装了所有MBean 和代理操作发生的异常。Listing 3.6 显示了ExceptionUtil 类:
Listing 3.6 ExceptionUtil.java
package jmxbook.ch3;
import javax.management.*;
public class  ExceptionUtil {
public static void printException( Exception e ) {
StringBuffer         exceptionName = new StringBuffer();
Exception            exc = null;
System.out.println("-------[ Exception ]-------");
e.printStackTrace();
if (e instanceof MBeanException ){
boolean hasEmbeddedExceptions = true;
Exception embeddedExc = e;
while (hasEmbeddedExceptions){
embeddedExc = (( MBeanException  )
embeddedExc).getTargetException();
System.out.println("-------[ Embedded Exception ]-------");
embeddedExc.printStackTrace();
if (!(embeddedExc instanceof MBeanException )){
hasEmbeddedExceptions = false;
}
}
}
}
}
这个类将会用在书中的很多例子中。
运行代理
我们已经构建了一个代理和RMI 客户端工厂,是时候测试一些代理了。本节我们将分别通过HTML 适配器和RMI 客户端来连接代理。 编译完之后就可以使用下面的命令运行了:
java jmxbook.ch3.JMXBookAgent
将会看到如下的输出:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> START of JMXBook Agent
>>> CREATE the agent ...
CREATE the MBeanServer .
Agent is Ready for Service...
之后可以通过HTML and RMI 来连接代理了。
3.5.1 使用浏览器连接
要连接到代理的HTML 适配器,打开浏览器输入http://localhost:9092 。浏览器中将会显示代理视图,其中应该显示三个MBean :适配器、连接器和MBeanServerDelegate (你可以使用这个代理重新做一下第二章HelloWorld 的例子)。
3.5.2 使用 RMI 客户端连接代理
要测试RMI 连接器,需要写一个小程序通过RMI 客户端去连接代理。这儿使用RMI 客户端将第二章的HelloWorld  MBean 注册进代理中,Listing 3.7 的HelloWorldSetup 类显示了这个过程。在本书的其他地方也将使用这种方式注册其他的MBean, 所以以后你还会经常看到这个类。
Listing 3.7 HelloWorldSetup .java
package jmxbook.ch3;
import javax.management.*;
import jmxbook.ch2.*;
import com.sun.jdmk.comm.*;
public class  HelloWorldSetup{
public HelloWorldSetup(){
try{
RmiConnectorClient client = RMIClientFactory .getClient();
ObjectName  hwName = new
ObjectName ( "JMXBookAgent :name=helloWorld");
client.createMBean( "jmxbook.ch2.HelloWorld ", hwName );
client.invoke( hwName, "printGreeting ", null, null );
}catch( Exception e ) {
e.printStackTrace();
}
}
public static void main( String args[] ){
HelloWorldSetup setup = new HelloWorldSetup ();
}
}
先别担心RMI 客户端的细节,只要记住它可以让你调用代理中的MBean server 的方法就行了,就像在上面例子中那样,调用了createMBean() 和invoke() 方法,这两个方法都直接对应MBeanServer  API 中的方法。
代理已经在运行了,编译并运行HelloWorldSetup 类,应该可以看到如下输出:
TYPE    = SUN RMI
PORT    = 2099
HOST    = t8100x0232
SERVER  = name=RmiConnectorServer
然后在代理的控制台上,你应该可以看到如下输出:
Hello World! I am a Standard MBean .
总结
本章我们为以后的很多例子准备了基础,通过创建JMXBookAgent   和RMIClientFactory   类,在以后的章节中用到代理时会节省很多时间。并且,籍此我们也有机会介绍了在以后章节中才会介绍的RMI 连接器。
本章我们创建的代理非常简单它与第二章的代理很相似,但是现在的JMXBookAgent 仅仅是一个基础,随着章节内容的推进,就要求代理有更多的特性 ,我们将渐渐的向它添加这些特性。
有了本章的基础,我们可以开始第四章了,第四章将通过标准MBean 来讨论MBean 的更多细节。
分享到:
上一篇:JMX IN ACTION---第二章