`
ss1
  • 浏览: 79792 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JMX在Tomcat中的应用(二)

阅读更多

下面,我们举一个简单的例子,理解一下 JMX 中中的各个概念。我们家有一个中央热水系统 (Central Heater System) ,它是我们家的一个资源,现在我们想通过 JMI 进行管理。现有的代码如下所示,当然,为简单起见,我们略去了一些 JNI 调用代码,因为厂家提供的 API 是用 C 语言写的。

a) 热水器接口 ( CentralHeaterInf .java ) 的现有代码:

package
carl.test.jmx;

/**
* The interface of Central Heater
* @author carlwu
*
*/
public interface CentralHeaterInf {

/**
* The heater is provided by British Gas Company
*/
public final static String HEATER_PROVIDER = "British Gas Company" ;

/**
* Get current temperature of heater
* @return the temperature of the heater
*/
public int getCurrentTemperature();


/**
* Set the new temperature
* @param newTemperature
*/
public void setCurrentTemperature( int newTemperature);


/**
* Turn on the heater
*/
public void turnOn();


/**
* Turn off the heater
*/
public void turnOff();

}


b) 热水器实现代码的现有代码 (CentralHeaterImpl .java )

/**
* The implemenation of Central Heater
* @author carlwu
*
*/
package carl.test.jmx;

public
class CentralHeaterImpl implements CentralHeaterInf {

int currentTemperature ;
public int getCurrentTemperature() {
  return currentTemperature ;
}

public void setCurrentTemperature( int newTemperature) {
  currentTemperature =newTemperature;
}

public void turnOff() {
  System. out .println( "The heater is off. " );
}

public void turnOn() {
  System. out .println( "The heater is on. " );
}

}


1.1
资源植入层 (Instrumentation Level) 代码示例

我们如何让
JMX 对我们的中央热水器进行管理呢 ? 首先,我们并不想让远程管理者能够关闭我们的中央热水器,因为热水器一旦关上,我们再也无法访问厂家提供的 API 。既然不能关闭它,我们的 MBeans 中也就不需要打开 (turnOn) 方法。所以,我们简单定义的 MBeans 接口如下:

package
carl.test.jmx;

/**
* @author carlwu
*
*/

public
interface CentralHeaterImplMBean {

/**
* return the heater provider
* @return
*/
public String getHeaterProvider();

/**
* Get current temperature of heater
* @return the temperature of the heater
*/
public int getCurrentTemperature();


/**
* Set the new temperature
* @param newTemperature
*/
public void setCurrentTemperature( int newTemperature);

/**
* Print the current temperature of the heater
* @return the string of current temperature
*/
public String printCurrentTemperature();

}

上面的 MBean 接口及其简单,意义也非常明显,我们只向管理程序公开热水器的生产厂家 ( 该属性为只读,管理程序不能更改热水器的生产厂家 ) ,但管理程序可以获取并更改当前热水器的温度,并且可以打印出热水器的当前温度。

接下来,我们要做的,就是更改我们已有的 CentralHeaterImpl.java 代码,让它实现 CentralHeaterImplMBean 接口,同时实现 CentralHeaterImplMBean MBean 中规定的所有方法。 CentralHeaterImpl.java 更改后的源代码如下:

/**
* The implemenation of Central Heater
* @author carlwu
*
*/
package carl.test.jmx;


public
class CentralHeaterImpl implements CentralHeaterInf,CentralHeaterImplMBean {

int currentTemperature ;

public int getCurrentTemperature() {
  return currentTemperature ;
}

public void setCurrentTemperature( int newTemperature) {
  currentTemperature =newTemperature;
}

public void turnOff() {
  System. out .println( "The heater is off. " );
}

public void turnOn() {
  System. out .println( "The heater is on. " );

}



public String getHeaterProvider() {
  // TODO Auto-generated method stub
  return HEATER_PROVIDER ;

}



public String printCurrentTemperature() {

  String printMsg= "Current temperature is:" + currentTemperature ;
  System. out .println(printMsg);
  return printMsg;
}

}

到此为止,我们的资源植入层 (Instrumentation Level) 的代码全部完成,它主要由一个 MBean(CentralHeaterImplBean) 及其实现类 CentralHeaterImpl 组成,在 CentralHeaterImplBean 这个 MBean 接口中,我们说明了要向管理程序暴露的属性和方法,在本例中,我们的管理程序可以访问热水器的生产厂家信息,同时还可以获取和设置并打印热水器的温度。在 MBean 的实现类中,我们实现了 MBean 接口中规定的所有方法。

然而,在上面的实现中,我们更改已有的 CentralHeaterImpl.java 代码。但从代码编写的角度看,这种做法违反了软件设计的基本原则 开闭原则。我们已有的 CentralHeaterImpl.java 类已经经过多次测试,消除了所有的 Bug ,现在为了支持 JMX ,我又增加方法,又修改代码,这会让原本运行得很好的系统重新产生 Bug 。您不妨思考一下,如何不修改 CentralHeaterImpl 类的代码,但又让使 JMX 能够管理我们家的热水器呢?请参考本文的附录,看看您的想法是否比我提供的参考实现高明些?

1.2 代理层 (Agent Level) 示例代码

import
java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

/**
* @author carlwu
*
*/
public class CentralHeaterAgent {
private static MBeanServer mBeanServer ;
/**
* @param args
*/

public static void main(String[] args) throws Exception {

  ObjectName oname;
  // get the default MBeanServer from Management Factory

 
mBeanServer = ManagementFactory.getPlatformMBeanServer ();
  // try {
  // create a instance of CentralHeaterImpl class
  CentralHeaterInf centralHeater = new CentralHeaterImpl();

  // assign a Object name to above instance
  oname = new ObjectName( "MyHome:name=centralheater" );

  // register the instance of CentralHeaterImpl to MBeanServer
  mBeanServer .registerMBean(centralHeater, oname);

  System. out .println( "Press any key to end our JMX agent..." );
  System. in .read();

}

}


您可以看到,上面的代理层代码异常简单。前面讲过,代理层中最重要的对象就是
MBeanServer ,我们可以把 MBeanServer 理解为一个全局的 HashMap ,所有的 MBeans 都通过唯一的名字注册到这个 HashMap ,这个 HashMap 可以跨越 JVM 访问,甚至可以通过 RMI Http 及其它手段跨越网络传输到其它机器,让其它机器也能访问这个 MBeanServer 中注册的对象。下面我们稍微理解一下代理层代码,在 main() 方法中,

a)   首先我们从 ManagementFactory 的工厂方法中获得 MBeanServer 对象;

b)   然后实例化我们的热水器对象,注意这个对象声明为 CentralHeaterInf ,而不是 CentralHeaterImplMBean JMX 规范并没有规定对象声明,只要这个对象实现了一个以 SomethingMBean 命名的接口或父类即可;

c)   接下来通过 new ObjectName(String) 构造函数给我们的 MBean 一个全局的名字,这个名字一般的格式是: 域名 : 属性 1=*, 属性 2=*,…” 构成;

d)   第四步,我们调用 MBeanServer regiesterBean 方法,通过第三步声明的全局名字把我们的 MBean 实例注册到 MBeanServer

这几步都非常简单明了。下面我们在 Eclipse 中运行代理层代码,运行时,请加上下面几个 JVM 运行时参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl="false"
-Dcom.sun.management.jmxremote.authenticate="false"

这四个 JVM 运行时参数的意义是, MBeanServer 允许其它管理程序通过 RMI 方式访问, RMI 端口是 9999 RMI 不使用 SSL 协议,也不需要验证。 Eclipse Run 窗口如下:


然后,请在上面的窗口中点击 Run( 运行 ) 按钮,运行代理层程序。

1.3 管理层代码

管理层代码编写起来其实也比较简单,但如果您要求界面比较完美,并且您也不想卷入到 AWT Swing 的面条代码中,您最好直接使用 JDK 自带的 JConsole.exe 程序,这个程序位于 JDK\bin 目录下,可直接运行。下面我们观察管理程序在远程和本地运行情况。

a)   远程运行 JConsole 管理程序

请双击 JConsole.exe 或者通过命令行在本机上启动 JConsole.exe ,在 JConsole 的连接界面,选择远程连接,然后输入 RMI 地址和端口号,本例为 localhost:9999 ,注意确保我们上面编写的 CentralHeaterAgent 代理处于运行状态,远程连接界面如下图所示:



连接成功后,请点击 MBean 标签,并展开 MyHome 节点,我们可以观察到 CentralHeaterImplMBean 中暴露给管理程序所有的属性和方法,如下图所示:



我们在
CentralHeaterImplMBean 接口中规定, CurrentTemperature 属性是可以更改的,所以上图中 CurrentTemperature 的值显示为绿色,表示远程管理者可以调节;但 HeaterProvider( 生产厂家 ) 的属性是不能更改的,所以其值显示为灰色。现在,我们以远程管理用户的身份,把 CurrentTemperature 属性的值改为 25 ,并按回车或者点击刷新按钮,接下来您可以在上面的界面中,调用操作方法 printCurrentTemperature() ,您会在弹出的对话框中看到“ Current temperature is:25 ”的字样,这说明我们的温度更改成功。请注意这是通过远程 RMI 完成的。

b)   本地运行 JConsole 管理程序

请关闭上步中打开的 JConsole ,然后重新运行 JConsole.exe 程序,选择本地进程中的 carl.test.jmx.CentralHeaterAgent 程序,并单击“连接”按钮,图示如下。




您在本地的管理程序中可以观察到,
MyHome 节点下的 centralheater CurrentTemperature 的值已经改为 25 ,这个更改时通过远程方式完成的。

到此为止, JMX 的小例子就结束了,您可能有些疑惑。 a) 首先, JMX 从表现形式上看似 RMI 或者 EJB ,是一种分布式计算,对吗? b) 其次,我们在注册 MBean 时,开始声明了一个 MBean 对象,然后把这个对象注册到 MBeanServer ,那么,所有的操作都只能操纵这个对象,对吧?假设我们在程序的其它地方,又新创建了这个 MBean 的另一个实例,这时,我们如何管理这个新创建的实例呢?

我们先来思考一下 JMX RMI/EJB 的区别, RMI/EJB 是分布式计算的一种,它们通过 Stub Skeleon 的方式,在服务器和客户端之间传输 Bean 实例,所以客户端必须知道服务器端 Bean 的接口;客户端可以获得服务器端的实例对象,并能调用这个实例对象的方法,被调用的方法其实是在客户端运行的,方法的运行需要占用客户端资源。但 JMX 不同, JMX 管理程序 ( 类似于 EJB/RMI 的客户端 ) 不需要了解服务器中 Bean 的任何接口的信息,更不需要从服务器上获取正在运行的实例,所有方法的调用均在服务器端完成,管理程序只是用来监视或者管理服务器中注册的 MBeans

再说说 JMX 如何管理新实例的问题,我们知道, JMX 管理的是资源。何谓资源,资源一般代表真实存在的事物。比如说上面例子中的热水器,我们家只有一个热水器,所以一个 MBean 的实例足矣,不必使用 new 来创建另一个实例。但是,您可能会问,我们家假如有两个热水器怎么办?在这种情况下,我们需要两个 MBean 的实例,把它们分别命名为 "MyHome:name=centralheater_1" "MyHome:name=centralheater_2" ,并注册到 MBeanServer ,这两个热水器之间没有任何关系,就和 Java 中同一个类的两个实例类似。当然,同一个类的两个实例之间可以通过 static 属性共享资源。一般说来, JMX 中的 MBean 对应的是真实世界里存在的事物,或者服务器中独一无二的对象,这些对象往往长期驻留在内存中,所以需要管理。如果您新建一个实例,等您的方法退出之后,垃圾回收器马上将这个对象清理掉,您也没有必要使用 JMX 来管理这种昙花一现的对象,对吗?

分享到:
评论
1 楼 lh870003574 2012-08-29  
1.1的示例中,针对你提出的对修改关闭的问题,没有找到你所说的附录...
我的想法是:应用门面模式(facade),新引入一个类,作为CentralHeaterImpl的门面,但只暴露CentralHeaterImplMBean所需要的方法。门面模式在tomcat中广为应用啊~~

相关推荐

    jmx 监控 tomcat

    在Tomcat这样的Java应用服务器中,JMX能够让我们深入洞察服务器的运行状态,包括内存使用、线程信息、MBean(Managed Beans)的属性和操作等。下面我们将详细介绍如何设置和使用JMX来监控Tomcat。 1. **开启JMX支持...

    jmx_tomcat_jboss

    在这个上下文中,“jmx_tomcat_jboss”涉及到的是如何通过JMX接口来对Apache Tomcat和Red Hat JBoss应用服务器进行监控和管理。这两个流行的Java应用服务器都支持JMX,以提供对内部组件和服务的远程访问,例如监控...

    基于Spring+JMX+Tomcat实现资源动态管理

    在IT行业中,动态资源管理是系统可扩展性和灵活性的关键因素之一。本文将深入探讨如何利用Spring框架、Java ...在实际工作中,这四个标签——jmx、spring、tomcat和jconsole——分别代表了资源管理的关键组件和技术。

    jmx 实现远程连接tomcat

    在tomcat目录下/bin/catalina.sh文件中,我们需要插入一行配置,用于启用jmx远程监控。配置内容如下: CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8888 -...

    tomcat开启远程jmx连接方式

    在Tomcat这样的Java应用服务器中,JMX可以帮助管理员监控和管理Tomcat的运行状态,如线程、内存使用、MBean等。以下是如何在不同版本的Tomcat(5、6、7)以及在Windows环境下开启远程JMX连接的详细步骤。 ### ...

    Monitoring Apache Tomcat with JMX.pdf

    Apache Tomcat是世界上最流行的开源Java Servlet容器,广泛用于部署Web应用程序。为了确保这些应用程序的稳定性和性能,对Tomcat...在实际操作中,结合日志分析和其他监控工具,可以构建出一个全面、高效的监控体系。

    jmx监控weblogic,tomcat,websphere源码

    在本项目中,"jmx监控weblogic,tomcat,websphere源码"涉及了使用JMX来监控三个主流的Java应用服务器:WebLogic、Tomcat和WebSphere。这些服务器都是企业级应用部署的常见选择,对它们的监控对于确保系统性能、稳定性...

    Tomcat开启JMX服务方法介绍

    主要介绍了Tomcat开启JMX服务方法的相关内容,小编觉得挺不错的,在这里给大家分享一下,需要的朋友可以参考。

    How Tomcat Work 第二章 实例应用

    Tomcat以其轻量级、高效和易于管理的特点,被广泛应用于各种规模的企业级应用中。 第二章主要围绕Tomcat的实际应用场景展开,涵盖了以下几个核心知识点: 1. **Tomcat的安装与配置**:首先,你需要知道如何在不同...

    boundary-plugin-jmx-tomcat:从 Apache Tomcat 实例收集指标

    在监控系统性能时,能够从 Tomcat 实例中收集指标至关重要,这有助于优化应用程序的效率,及时发现并解决问题。"boundary-plugin-jmx-tomcat" 是一个专门用于此目的的工具,它利用 Java Management Extensions (JMX)...

    zabbix监控tomcat所需的cmdline-jmxclient-0.10.3.jar和zbx自定义模版

    本文将深入探讨如何使用Zabbix监控Tomcat应用服务器,特别关注"cmdline-jmxclient-0.10.3.jar"工具以及相关的自定义模板。 首先,`cmdline-jmxclient-0.10.3.jar`是一个Java管理扩展(JMX)客户端,它允许通过...

    cmdline-jmxclient-0.10.3.jar + zabbix tomcat监控模板

    本文将详细讲解如何利用`cmdline-jmxclient-0.10.3.jar`工具与Zabbix集成,实现对Tomcat应用服务器的高效监控。 首先,`cmdline-jmxclient-0.10.3.jar`是一个命令行Java Management Extensions (JMX)客户端,它允许...

    tomcat中文手册.chm

    由于其小巧、高效和免费的特性,Tomcat在小型到中型的Web应用中得到了广泛应用。 二、Tomcat安装与配置 1. 安装:下载Tomcat的最新稳定版本,解压到指定目录,无需复杂安装过程。 2. 配置:修改`conf/server.xml`...

    Tomcat源码研究.pdf

    深入研究容器的实现可以帮助我们理解如何在Java Web应用中处理HTTP请求。 6. 生命周期:Tomcat中每个组件都有自己的生命周期。理解生命周期对于理解整个Tomcat的运作至关重要。例如,我们可以通过生命周期方法来...

    cmdline-jmxclient.zip

    标题“cmdline-jmxclient.zip”指的是一个包含命令行界面的Java管理扩展(JMX)客户端工具,这个工具主要用于远程连接并监控Java虚拟机(JVM)以及运行在其中的应用,比如Tomcat服务器。JMX是一种Java平台提供的标准...

    tomcat_weblogic_jmx.txt

    为了在 Apache Tomcat 中启用 JMX,首先需要修改 Tomcat 的启动脚本,即 `catalina.sh` 文件。在文件中添加以下行: ```bash CATALINA_OPTS="${CATALINA_OPTS}-Djava.rmi.server.hostname=162.16.10.53" CATALINA_...

    zabbix 监控 tomcat

    首先,需要在 Tomcat 的配置文件中添加 JMX 相关的参数,然后重启 Tomcat 服务器。这样,Tomcat 就可以被 Zabbix 监控了。 Zabbix 监控 Tomcat 的实现 在 Zabbix 中,可以通过 JMX 监控 Tomcat 的性能和状态。...

    tomcat中文手册

    Tomcat作为一个开源的Servlet容器,是Java EE应用中的关键组件,尤其在轻量级Web应用程序部署方面表现突出。下面将根据手册内容,深入探讨Tomcat的相关知识点。 一、Tomcat概述 Tomcat是Apache软件基金会Jakarta...

Global site tag (gtag.js) - Google Analytics