JMX官网教程的翻译

JMX官网教程的翻译

官网原文地址


JMX的简介–提供了对JMX技术的简要描述,包括其目的和主要特性。

JMX的架构–介绍JMX技术的基本概念,即管理bean,也称为mbean。本课还介绍了mxbean。

JMX的通知机制–介绍了JMX技术的通知机制。

JMX远程管理–展示了如何实现JMX API的远程管理功能以及如何创建JMX客户机应用程序。


JMX的概览

Java管理扩展(JMX)技术是Java平台标准版(Java SE平台)的一个标准部分。JMX技术是在Java 2平台标准版(J2SE) 5.0发行版中添加到该平台的。

JMX技术提供了一种简单、标准的方式来管理应用程序、设备和服务等资源。因为JMX技术是动态的,所以您可以使用它在创建、安装和实现资源时监视和管理资源。您还可以使用JMX技术监视和管理Java虚拟机(Java VM)。

JMX规范用Java编程语言定义了体系结构、设计模式、api和服务,用于管理和监视应用程序和网络。

使用JMX技术,给定的资源由一个或多个Java对象(称为Managed bean或mbean)进行检测。这些MBean注册在一个核心管理的对象服务器(称为MBean服务器)中。MBean服务器充当管理代理,可以在启用了Java编程语言的大多数设备上运行。

这些规范定义了用于管理已正确配置为管理的任何资源的JMX代理。JMX代理由一个MBean服务器(MBean在其中注册)和一组用于处理MBean的服务组成。通过这种方式,JMX代理直接控制资源,并使它们可供远程管理应用程序使用。

配置资源的方式完全独立于管理基础设施。因此,无论资源的管理应用程序是如何实现的,都可以将资源呈现为可管理的。

JMX技术定义了标准连接器(称为JMX连接器),使您能够从远程管理应用程序访问JMX代理。使用不同协议的JMX连接器提供相同的管理接口。因此,无论使用何种通信协议,管理应用程序都可以透明地管理资源。不符合JMX规范的系统或应用程序也可以使用JMX代理,只要这些系统或应用程序支持JMX代理。

为什么使用JMX技术?

JMX技术为开发人员提供了一种灵活的方法,可以配置基于Java技术的应用程序(Java应用程序)、创建智能代理、实现分布式管理中间件和管理器,并将这些解决方案顺利集成到现有的管理和监视系统中。

  • JMX技术使管理Java应用程序无需大量投入。

    基于JMX技术的代理(JMX代理)可以在大多数启用Java技术的设备上运行。因此,Java应用程序可以变得易于管理,而对其设计几乎没有影响。Java应用程序只需要嵌入一个托管对象服务器,并使其某些功能作为在对象服务器中注册的一个或几个托管bean (mbean)可用。这就是从管理基础设施中获益所需要的全部内容。

  • JMX技术提供了一种管理Java应用程序、系统和网络的标准方法。

    例如,Java Platform, Enterprise Edition (Java EE) 5 Application Server符合JMX体系结构,因此可以使用JMX技术进行管理。

  • JMX技术可用于Java VM的开箱即用管理。

    Java虚拟机(Java VM)使用JMX技术进行了高度检测。您可以启动JMX代理来访问内置的Java VM工具,从而远程监视和管理Java VM。

  • JMX技术提供了可伸缩的动态管理体系结构。

    每个JMX代理服务都是一个独立的模块,可以根据需求插入到管理代理中。这种基于组件的方法意味着JMX解决方案可以从占用空间小的设备扩展到大型电信交换机等。JMX规范提供了一组核心代理服务。可以在管理基础结构中开发和动态加载、卸载或更新其他服务。

  • JMX技术利用了现有的标准Java技术。

    只要需要,JMX规范就会引用现有的Java规范,例如Java命名和目录接口(J.N.D.I.)。API。

  • 基于JMX技术的应用程序(JMX应用程序)可以从NetBeans IDE模块创建。

    您可以从NetBeans更新中心(在NetBeans界面中选择Tools -> Update Center)获得一个模块,该模块使您能够使用NetBeans IDE创建JMX应用程序。这降低了JMX应用程序的开发成本。

  • JMX技术集成了现有的管理解决方案和新兴技术。

    JMX api是任何管理系统供应商都可以实现的开放接口。JMX解决方案可以使用查找和发现服务和协议,如Jini网络技术和服务位置协议(Service Location Protocol, SLP)。

JMX的技术原型

JMX技术可分为以下三个层次:

  • 仪表 Instrumentation
  • JMX代理
  • 远程管理

仪表

要使用JMX技术管理资源,首先必须用Java语言为资源装上仪器。您使用称为mbean的Java对象来实现对资源仪器的访问。MBean必须遵循JMX规范中定义的设计模式和接口。这样做可以确保所有MBean以标准化的方式提供托管资源插装。除了标准MBean之外,JMX规范还定义了一种特殊类型的MBean,称为MXBean。MXBean是只引用一组预定义的数据类型的MBean。还有其他类型的MBean,但本文将集中讨论标准MBean和MXBean。

一旦mbean检测了资源,就可以通过JMX代理对其进行管理。MBean不需要了解它们将使用的JMX代理。

MBean的设计是灵活、简单和易于实现的。应用程序、系统和网络的开发人员可以使他们的产品以一种标准的方式进行管理,而不必了解或投资于复杂的管理系统。现有的资源可以用最少的努力来管理。

此外,JMX规范的检测级别提供了一种通知机制。这种机制使MBean能够生成通知事件并将其传播到其他级别的组件。

JMX代理

基于JMX技术的代理(JMX代理)是一种标准的管理代理,它直接控制资源并使其可供远程管理应用程序使用。JMX代理通常与它们控制的资源位于同一台机器上,但这种安排不是必需的。

JMX代理的核心组件是MBean服务器,这是一个注册MBean的托管对象服务器。JMX代理还包括一组用于管理MBean的服务,以及至少一个通信适配器或连接器,以允许管理应用程序访问。

在实现JMX代理时,您不需要知道它将管理的资源的语义或功能。实际上,JMX代理甚至不需要知道它将为哪些资源提供服务,因为任何符合JMX规范的资源都可以使用提供资源所需服务的任何JMX代理。类似地,JMX代理不需要知道将访问它的管理应用程序的功能。

远程管理

可以通过许多不同的方式访问JMX技术工具,既可以通过现有的管理协议,如简单网络管理协议(SNMP),也可以通过专有协议。MBean服务器依靠协议适配器和连接器使JMX代理可以从代理的Java虚拟机(Java VM)外部的管理应用程序访问。

每个适配器通过在MBean服务器中注册的所有MBean的特定协议提供一个视图。例如,HTML适配器可以在浏览器中显示MBean。

连接器提供了一个管理器端接口,用于处理管理器和JMX代理之间的通信。每个连接器通过不同的协议提供相同的远程管理接口。当远程管理应用程序使用此接口时,它可以通过网络透明地连接到JMX代理,而不考虑协议。JMX技术为基于Java远程方法调用(Java remote Method Invocation, Java RMI)将JMX技术工具导出到远程应用程序提供了一个标准解决方案。

Java虚拟机的监控和管理

JMX技术还可用于监视和管理Java虚拟机(Java VM)。

Java VM具有内置的工具,使您能够通过使用JMX技术对其进行监视和管理。这些内置的管理实用程序通常被称为Java VM的开箱即用管理工具。为了监视和管理Java VM的不同方面,Java VM包括一个平台MBean服务器和特殊的MXBean,供符合JMX规范的管理应用程序使用。

平台MXBean和平台MBean服务器

平台MXBean是Java SE平台提供的一组MXBean,用于监视和管理Java虚拟机和Java运行时环境(JRE)的其他组件。每个平台MXBean都封装了Java VM功能的一部分,例如类加载系统、即时(JIT)编译系统、垃圾收集器等等。通过使用符合JMX规范的监视和管理工具,可以显示这些MXBean并与之交互,从而使您能够监视和管理这些不同的VM功能。其中一个监视和管理工具是Java SE平台的JConsole图形用户界面(GUI)。

Java SE平台提供了一个标准的平台MBean服务器,这些平台MXBean在其中注册。平台MBean服务器还可以注册您希望创建的任何其他MBean。

JConsole

Java SE平台包括JConsole监控和管理工具,该工具符合JMX规范。JConsole使用Java VM(平台MXBeans)的广泛工具来提供有关在Java平台上运行的应用程序的性能和资源消耗的信息。JConsole 使用 Java VM(平台 MXBeans)的大量工具来提供在 Java 平台上运行的应用程序的性能和资源消耗信息。

开箱即用的管理

由于实现JMX技术的标准监视和管理实用程序内置于Java SE平台中,因此无需编写一行JMX API代码,就可以看到开箱即用的JMX技术。可以通过启动Java应用程序,然后使用JConsole对其进行监视来实现。

使用JConsole监控应用程序

这个过程展示了如何监视Notepad Java应用程序。在版本6之前的Java SE平台版本中,需要使用以下选项启动希望使用JConsole监视的应用程序。

-Dcom.sun.management.jmxremote

但是,Java SE 6平台提供的JConsole版本可以附加到任何支持attach API的本地应用程序。换句话说,在Java SE 6 HotSpot VM中启动的任何应用程序都由JConsole自动检测,不需要使用上述命令行选项启动。

  1. 在终端窗口或命令行窗口,使用下面的命令启动Notepad Java应用程序

    java -jar 
        jdk_home/demo/jfc/Notepad/Notepad.jar
    

    jdk_homeJDK安装的目录。如果你运行是Java SE 6之前的平台,你需要使用下面的命令:

    java -Dcom.sun.management.jmxremote -jar 
          jdk_home/demo/jfc/Notepad/Notepad.jar
    
  2. 一旦Notepad打开了,在不同的终端窗口或命令行窗口,使用下面的命令行启动JConsole:

    jconsole
    

    一个“新建连接”对话框就会出来。

  3. 在“新建连接”对话框中,从本地进程列表选择Notepad.jar,点击“连接”按钮。

    JConsole 会打开并连接到 "Notepad.jar "进程。打开 JConsole 后,您将看到与记事本相关的监控和管理信息概览。例如,您可以查看应用程序占用的堆内存量、应用程序当前运行的线程数以及应用程序占用的中央处理器(CPU)容量。

  4. 点击不同的JConsole标签.

    每个选项卡都提供了有关运行记事本的 Java 虚拟机不同功能区域的详细信息。所显示的所有信息均来自本跟踪中提到的各种 JMX 技术 MXBeans。所有平台 MXBeans 都可以在 MBeans 选项卡中显示。MBeans 选项卡将在本小节的下一部分进行介绍。

  5. 要想关闭JConsole,选择连接*->*退出。


MBean基础知识

介绍JMX API的基本概念,即托管BeansMBeans

MBean是一个托管Java对象,类似于JavaBeans组件,它遵循JMX规范中规定的设计模式。MBean可以表示需要管理的设备、应用程序或任何资源。MBean公开了一个管理接口,它由以下内容组成:

  • 一组可读或可写属性,或两者兼而有之。

  • 一组可调用的操作。

  • 自我描述。

管理接口在MBean实例的整个生命周期中不会更改。MBean还可以在发生某些预定义事件时发出通知。

JMX规范定义了五种类型的MBean:

  • 标准MBean
  • 动态MBean
  • Open MBean
  • 模型MBean
  • MXBean

本文中的示例只演示了最简单的MBean类型,即标准MBean和MXBean。

标准MBean

本节提供了一个简单的标准MBean示例。

标准MBean是通过编写名为SomethingMBean的Java接口和实现该接口的名为Something的Java类来定义的。接口中的每个方法在MBean中定义一个属性或一个操作。默认情况下,每个方法定义一个操作。属性和操作是遵循特定设计模式的方法。标准MBean由一个MBean接口和一个类组成。MBean接口列出了所有公开属性和操作的方法。这个类实现了这个接口,并提供了仪器化资源的功能。

下面几节将研究一个标准MBean的示例和一个管理MBean的支持JMX技术的简单代理(JMX代理)。

MBean Interface

package com.example; 
 
public interface HelloMBean { 
 
    public void sayHello(); 
    public int add(int x, int y); 
    
    public String getName(); 
     
    public int getCacheSize(); 
    public void setCacheSize(int size); 
} 

按照约定,MBean接口采用实现它的Java类的名称,并添加后缀MBean。在本例中,接口称为HelloMBean。

根据JMX规范,MBean接口除了由MBean管理的应用程序可以调用的命名和类型化操作外,还包括可读和可能可写的命名和类型化属性。HelloMBean接口声明了两个操作:Java方法add()sayHello()

HelloMBean声明了两个属性:Name是一个只读字符串,而CacheSize是一个既可以读也可以写的整数。声明Getter和setter方法以允许托管应用程序访问并可能更改属性值。根据JMX规范的定义,getter是任何不返回void且名称以get开头的公共方法。getter使管理器能够读取属性的值,属性的类型是返回对象的类型。setter是任何接受单个参数且名称以set开头的公共方法。设置器使管理器能够在属性中写入新值,该值的类型与参数的类型相同。

这些操作和属性的实现将在下一节中展示。

MBean Implementation

package com.example; 
 
public class Hello ... 
    implements HelloMBean { 
    public void sayHello() { 
        System.out.println("hello, world"); 
    } 
     
    public int add(int x, int y) { 
        return x + y; 
    } 
     
    public String getName() { 
        return this.name; 
    }  
     
    public int getCacheSize() { 
        return this.cacheSize; 
    } 
     
    public synchronized void setCacheSize(int size) {
        ...
    
        this.cacheSize = size; 
        System.out.println("Cache size now " + this.cacheSize); 
    } 
    ...
     
    private final String name = "Reginald"; 
    private int cacheSize = DEFAULT_CACHE_SIZE; 
    private static final int 
        DEFAULT_CACHE_SIZE = 200; 
}

简单的Hello类提供了由HelloMBean声明的操作和属性的定义。sayHello()和add()操作非常简单,但实际操作可以根据需要简单或复杂。

还定义了获取Name属性和获取和设置CacheSize属性的方法。在本例中,Name属性值永远不会改变。但是,在实际场景中,这个属性可能会随着托管资源的运行而改变。例如,该属性可能表示正常运行时间或内存使用等统计信息。在这里,属性仅仅是名称Reginald。

调用setCacheSize方法使您能够从其声明的默认值200更改CacheSize属性。在实际场景中,更改CacheSize属性可能需要执行其他操作,例如丢弃条目或分配新条目。此示例仅打印一条消息,以确认缓存大小已更改。但是,可以定义更复杂的操作,而不是简单地调用println()。

创建JMX代理来管理资源

一旦MBean对资源进行了检测,该资源的管理将由JMX代理执行。

JMX代理的核心组件是MBean服务器。MBean服务器是注册MBean的托管对象服务器。JMX代理还包括一组管理MBean的服务。有关MBean服务器实现的详细信息,请参阅MBeanServer接口的API文档。

package com.example; 
 
import java.lang.management.*; 
import javax.management.*; 
 
public class Main { 
 
    public static void main(String[] args) 
        throws Exception { 
     
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
        ObjectName name = new ObjectName("com.example:type=Hello"); 
        Hello mbean = new Hello(); 
        mbs.registerMBean(mbean, name); 
          
        ...
     
        System.out.println("Waiting forever..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 
} 

通过调用java.lang.management.ManagementFactory类的getPlatformMBeanServer()方法,JMX代理Main首先获得一个由平台创建并初始化的MBean服务器。如果平台还没有创建MBean服务器,那么getPlatformMBeanServer()通过调用JMX方法MBeanServerFactory.createMBeanServer()自动创建一个MBean服务器。Main获取的MBeanServer实例名为mbs。

接下来,Main为它将要创建的MBean实例定义一个对象名称。每个JMX MBean都必须有一个对象名。对象名是JMX类ObjectName的一个实例,必须符合JMX规范定义的语法。也就是说,对象名称必须包含一个域和一个键属性列表。在Main定义的对象名称中,域为com.example(包含示例MBean的包)。另外,key属性声明该对象的类型为Hello。

将创建一个名为MBean的Hello对象实例。然后,通过将对象和对象名称传递给对JMX方法MBeanServer.registerMBean()的调用,将名为MBean的Hello对象在mbean服务器mbs中注册为MBean,并使用对象名称name。

在MBean服务器中注册了Hello MBean后,Main只需等待对Hello执行管理操作。

运行这个标准MBean的例子

检查了示例类之后,现在可以运行示例了。在本例中,JConsole用于与MBean交互。

  1. 保存JMX例子的压缩包 jmx_examples.zip到你的工作目录work_dir。

  2. 在命令行或者终端使用下面的命令解压缩这个包:unzip jmx_examples.zip。

    unzip jmx_examples.zip
    
  3. 在work_dir目录下编译例子中所有类:

    javac com/example/*.java
    
  4. 如果你运行的是JDK6,就用下面的命令行启动Main应用

    java com.example.Main
    

    如果运行的 JDK 版本早于版本 6,则需要在启动 "Main "应用程序时指定以下选项,以便将应用程序用于监控和管理。

    java -Dcom.sun.management.jmxremote example.Main
    

    显示 "Main "正在等待某事发生的确认信息。

  5. 在同一台机器上打开一个新的命令行或者终端窗口,输入命令jconsole启动jconsole。

    新建连接 "对话框将显示,其中列出了可以连接的运行中的 JMX 代理。

  6. 在 "新建连接 "对话框中,从列表中选择 “com.example.Main”,然后单击 “连接”。

    将显示平台当前活动的摘要。

  7. 单击 MBeans 选项卡。

    该面板显示当前在 MBean 服务器中注册的所有 MBean。

  8. 在左侧框架中,展开 MBean 树中的 "com.example "节点。

    您将看到由 Main创建并注册的示例 MBean Hello。如果单击 Hello,就会在 MBean 树中看到其相关的属性和操作节点。

  9. 在 MBean 树中展开 Hello MBean 的属性节点。

    显示由 Hello 类定义的 MBean 属性。

  10. 将 CacheSize 属性的值改为 150。

    在启动 Main 的终端窗口中,会生成该属性更改的确认信息。

  11. 在 MBean 树中展开 Hello MBean 的 Operations 节点。

    可以看到由 Hello MBean 声明的两个操作 sayHello()add()

  12. 单击 sayHello 按钮,调用 sayHello() 操作。

    JConsole 对话框会通知你方法已成功调用。信息 "hello, world " 将在运行 Main 的终端窗口中生成。

  13. 为 add() 操作提供两个要添加的整数,然后单击添加按钮。

    答案将显示在 JConsole 对话框中。

  14. 要关闭 JConsole,请选择连接 -> 退出。

MXBeans

本节解释一种特殊类型的MBean,称为MXBeans。

MXBean是一种MBean类型,它只引用一组预定义的数据类型。通过这种方式,您可以确保您的MBean可以被任何客户端使用,包括远程客户端,而不需要客户端能够访问代表MBean类型的特定于模型的类。MXBean提供了一种方便的方法来将相关的值捆绑在一起,而不需要对客户机进行特殊配置来处理这些捆绑。

与标准MBean一样,MXBean是通过编写一个名为SomethingMXBean的Java接口和实现该接口的Java类来定义的。然而,与标准MBean不同的是,MXBean不需要将Java类命名为Something。接口中的每个方法在MXBean中定义一个属性或一个操作。注释@MXBean也可以用来注释Java接口,而不是要求接口名后面跟着MXBean后缀。

MXBeans存在于Java 2 Platform, Standard Edition (J2SE) 5.0软件中,在包Java .lang.management中。但是,除了在java.lang.management中定义的标准集之外,用户现在可以定义他们自己的mxbean。

MXBean背后的主要思想是,在MXBean接口(本例中是java.lang.management.MemoryMXBean)中引用的java.lang.management.MemoryUsage等类型被映射到一组标准类型,即在包javax.management.openmbean中定义的所谓开放类型。确切的映射规则出现在MXBean规范中。然而,一般原则是简单类型(如int或String)保持不变,而复杂类型(如MemoryUsage)映射到标准类型CompositeDataSupport

MXBean示例由以下文件组成,它们位于jmx_examples.zip中:

  • QueueSamplerMXBean:接口
  • QueueSampler:实现了MXBean接口的类
  • QueueSample:MXBean接口中的getQueueSample()方法的返回值类型
  • Main:设置和运行示例的程序。

MXBean示例使用这些类来执行以下操作:

  • 定义一个简单的MXBean来管理Queue<String>类型的资源

  • 在MXBean中声明getter getQueueSample,它在调用时获取队列快照,并返回一个Java类QueueSample,该类将以下值捆绑在一起:

    • 快照的时间
    • 队列大小
    • 在给定时间的队列头
  • 在MBean服务器中注册MXBean

MXBean Interface

package com.example; 
 
public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 
} 

注意,声明MXBean接口的方式与声明标准MBean接口的方式完全相同。QueueSamplerMXBean接口声明了一个getter getQueueSample和一个操作clearQueue。

定义MXBean 操作

package com.example; 
 
import java.util.Date; 
import java.util.Queue; 
 
public class QueueSampler 
                implements QueueSamplerMXBean { 
     
    private Queue<String> queue; 
         
    public QueueSampler (Queue<String> queue) { 
        this.queue = queue; 
    } 
         
    public QueueSample getQueueSample() { 
        synchronized (queue) { 
            return new QueueSample(new Date(), 
                           queue.size(), queue.peek()); 
        } 
    } 
         
    public void clearQueue() { 
        synchronized (queue) { 
            queue.clear(); 
        } 
    } 
} 

QueueSampler定义了getQueueSample() 和clearQueue()操作,它们由MXBean接口声明。getQueueSample()操作返回一个QueueSample类的实例,该实例是用java.util.Queue方法peek()和size()返回的值创建的,以及一个java.util.Date的实例。

定义由MXBean接口返回的Java类型

到目前为止,已经定义了以下内容:MXBean接口和实现它的类,以及返回的Java类型。接下来,必须在MBean服务器中创建并注册MXBean。这些操作是由在标准MBean示例中使用的同一个Main示例JMX代理执行的,但是在标准MBean课程中没有显示相关代码。

package com.example; 
 
import java.lang.management.ManagementFactory; 
import java.util.Queue; 
import java.util.concurrent.ArrayBlockingQueue; 
import javax.management.MBeanServer; 
import javax.management.ObjectName; 
 
public class Main { 
 
    public static void main(String[] args) throws Exception { 
        MBeanServer mbs = 
            ManagementFactory.getPlatformMBeanServer(); 
                
        ...  
        ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler");
        
        Queue<String> queue = new ArrayBlockingQueue<String>(10);
        queue.add("Request-1");
        queue.add("Request-2");
        queue.add("Request-3");
        QueueSampler mxbean = new QueueSampler(queue);
        
        mbs.registerMBean(mxbean, mxbeanName);
                 
        System.out.println("Waiting..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 
} 

Main类执行以下操作:

  • 获取平台MBean服务器。
  • 为MXBean QueueSampler创建对象名称。
  • 为QueueSampler MXBean创建要处理的Queue实例。
  • 将Queue实例提供给新创建的QueueSampler MXBean。
  • 以与标准MBean完全相同的方式在MBean服务器中注册MXBean。

Running the MXBean Example

MXBean 示例使用了 标准 MBeans 部分中使用的 jmx_examples.zip捆绑包中的类。该示例需要 Java SE 平台的第 6 版。要运行 MXBeans 示例,请按以下步骤操作:

  1. 如果您还没有这样做,请将 jmx_examples.zip保存到您的 work_dir 目录中。

  2. 在命令行或者终端使用下面的命令解压缩这个包:

    unzip jmx_examples.zip
    
  3. 在work_dir目录下编译例子中所有类:

    javac com/example/*.java
    
  4. 启动Main应用.确认显示Main正在等待一些事情发生.

    java com.example.Main
    
  5. 在同一台机器上打开一个新的命令行或者终端窗口,启动JConsole。新建连接对话框将会显示出来,列表中显示出可以连接的正在运行的JMX代理。

    jconsole
    
  6. 在新建连接对话框中,从列表中选择com.example.Main中,并点击connect。这时,平台的当前活动的概述将会显示出来。

  7. 点击MBean标签,这个面板将会显示所有当前注册到MBean服务器中的MBean。

  8. I在左边的MBean树中,展开com.example节点。你会看到在Main创建并注册的MBean QueueSampler。如果你点击QueueSampler,你会在MBean树中看到它关联的“属性”和“操作”节点。

  9. 展开“属性”节点。你将会看到属性QueueSample出现在右边的面板,还有它的值javax.management.openmbean.CompositeDataSupport。

  10. 双击 CompositeDataSupport 值。

    您将看到 QueueSampledateheadsize,因为 MXBean 框架已将 QueueSample 实例转换为 CompositeData。如果将 QueueSampler 定义为标准 MBean 而不是 MXBean,JConsole 就不会找到 QueueSample 类,因为它不在类路径中。如果 QueueSampler 是一个标准的 MBean,那么在检索 QueueSample 属性值时就会收到一条 ClassNotFoundException 消息。JConsole 能找到 QueueSampler 这一事实表明,在通过通用 JMX 客户端(如 JConsole)连接 JMX 代理时,使用 MXBean 非常有用。

  11. 展开操作节点。

    将显示调用 "clearQueue "操作的按钮。

  12. 单击 clearQueue 按钮。

    将显示方法已成功调用的确认信息。

  13. 再次展开属性节点,双击 CompositeDataSupport 值。

    headsize值已被重置。

  14. 要关闭 JConsole,请选择连接 -> 退出。


JMX的通知机制

JMX API定义了一种机制,使mbean能够生成通知,例如,发出状态更改、检测到的事件或问题的信号。

要生成通知,MBean必须实现NotificationEmitter接口或扩展notificationbroadastersupport。要发送通知,需要构造类javax.management.Notification的实例或子类(如AttributeChangedNotification),并将实例传递给notificationbroadastersupport . sendnotification。

每个通知都有一个源。源是生成通知的MBean的对象名称。

每个通知都有一个序列号。当订单很重要,并且存在以错误顺序处理通知的风险时,此号码可用于订购来自同一来源的通知。序列号可以为零,但最好是每个来自给定MBean的通知都增加序列号。

标准MBean中的Hello MBean实现实际上实现了通知机制。然而,为了简单起见,这段代码在那一课中被省略了。Hello的完整代码如下:

package com.example;

import javax.management.*;

public class Hello
        extends NotificationBroadcasterSupport
        implements HelloMBean {

    public void sayHello() {
        System.out.println("hello, world");
    }

    public int add(int x, int y) {
        return x + y;
    }

    public String getName() {
        return this.name;
    }

    public int getCacheSize() {
        return this.cacheSize;
    }

    public synchronized void setCacheSize(int size) {
        int oldSize = this.cacheSize;
        this.cacheSize = size;

        System.out.println("Cache size now " + this.cacheSize);

        Notification n = new AttributeChangeNotification(this,
                                sequenceNumber++, System.currentTimeMillis(),
                                "CacheSize changed", "CacheSize", "int",
                                oldSize, this.cacheSize);

        sendNotification(n);
    }

    @Override
    public MBeanNotificationInfo[] getNotificationInfo() {
        String[] types = new String[]{
            AttributeChangeNotification.ATTRIBUTE_CHANGE
        };

        String name = AttributeChangeNotification.class.getName();
        String description = "An attribute of this MBean has changed";
        MBeanNotificationInfo info = 
                new MBeanNotificationInfo(types, name, description);
        return new MBeanNotificationInfo[]{info};
    }
    
    private final String name = "Reginald";
    private int cacheSize = DEFAULT_CACHE_SIZE;
    private static final int DEFAULT_CACHE_SIZE = 200;
    private long sequenceNumber = 1;
}

这个Hello MBean实现扩展了NotificationBroadcasterSupport类。NotificationBroadcasterSupport实现NotificationEmitter接口。

操作和属性的设置方式与标准MBean示例中相同,不同之处在于,CacheSize属性的setter方法现在定义了一个oldSize的值。该值记录设置操作之前的CacheSize属性的值。

通知是由JMX类AttributeChangeNotification的实例n构造的,它扩展了javax.management.Notification。通知是在setCacheSize()方法的定义中根据以下信息构造的。该信息作为参数传递给AttributeChangeNotification

  • 通知源的对象名称,即Hello MBean,由this表示
  • 序列号,即sequenceNumber,设置为1,并以增量方式增加
  • 一个时间戳
  • 通知消息的内容
  • 已更改的属性的名称,在本例中为CacheSize
  • 已更改的属性类型
  • 旧的属性值,在本例中为oldSize
  • 新的属性值,在本例中是this. cachesize
  • 然后将通知传递给NotificationBroadcasterSupport.sendnotification()方法。

最后,定义MBeanNotificationInfo实例来描述由MBean为给定类型的通知生成的不同通知实例的特征。在这种情况下,发送的通知类型是AttributeChangeNotification通知。

运行 MBean 通知示例

你将再一次使用JConsole与Hello MBean进行交互,这一次是用于发送和接收通知。这个示例需要Java SE6。

  1. 如果您还没有这样做,请将 jmx_examples.zip保存到您的 work_dir 目录中。

  2. 在命令行或者终端使用下面的命令解压缩这个包:

    unzip jmx_examples.zip
    
  3. 在work_dir目录下编译例子中所有类:

    javac com/example/*.java
    
  4. 启动Main应用.确认显示Main正在等待一些事情发生.

    java com.example.Main
    
  5. 在同一台机器上打开一个新的命令行或者终端窗口,启动JConsole。新建连接对话框将会显示出来,列表中显示出可以连接的正在运行的JMX代理。

    jconsole
    
  6. 在新建连接对话框中,从列表中选择com.example.Main中,并点击connect。这时,平台的当前活动的概述将会显示出来。

  7. 单击 MBeans 选项卡。

    此面板显示当前在 MBean 服务器中注册的所有 MBean。

  8. 在左侧框架中,展开 MBean 树中的 com.example 节点。

    您将看到由 Hello 创建并注册的示例 MBean Hello。如果单击 Hello,就会在 MBean 树中看到其 "通知 "节点。

  9. 在 MBean 树中展开 Hello MBean 的 Notifications 节点。

    注意面板是空白的。

  10. 单击 Subscribe(订阅)按钮。

    当前收到的通知数(0)将显示在 "通知 "节点标签中。

  11. 展开 MBean 树中 Hello MBean 的 Attributes 节点,并将 CacheSize 属性的值更改为 150。

    在启动 Main 的终端窗口中,将显示属性更改的确认信息。请注意,"通知 "节点中显示的已收到通知数量已变为 1。

  12. 再次展开 MBean 树中 Hello MBean 的通知节点。

    显示通知的详细信息。

  13. 要关闭 JConsole,请选择连接 -> 退出。


远程管理

通过使用基于JMX技术的连接器(JMX连接器),JMX API使您能够对资源执行远程管理。JMX连接器使基于Java技术的远程客户机可以访问MBean服务器。连接器的客户端基本上导出与MBean服务器相同的接口。

JMX连接器由连接器客户机和连接器服务器组成。连接器服务器连接到MBean服务器并侦听来自客户机的连接请求。连接器客户端负责建立与连接器服务器的连接。连接器客户机通常位于与连接器服务器不同的Java虚拟机(Java VM)中,并且通常运行在不同的机器上。JMX API定义了一个基于远程方法调用(RMI)的标准连接协议。该协议使您能够从远程位置将JMX客户机连接到MBean服务器中的MBean,并在MBean上执行操作,就像在本地执行操作一样。

Java SE平台提供了一种开箱即用的方法,通过使用JMX API的标准RMI连接器远程监视应用程序。开箱即用的RMI连接器自动公开应用程序以进行远程管理,而不需要您自己创建专用的远程连接器服务器。通过使用正确的属性启动Java应用程序来激活开箱即用的远程管理代理。然后,与JMX技术兼容的监视和管理应用程序可以连接到这些应用程序并远程监视它们。

通过JConsole公开资源进行远程管理

如果使用开箱即用的远程管理代理和现有的监视和管理工具(如JConsole),通过使用JMX API公开Java应用程序进行远程管理可能非常简单。

要公开应用程序进行远程管理,需要使用正确的属性启动它。这个例子展示了如何公开主JMX代理进行远程管理。

安全考虑:

为了简单起见,在本例中禁用了身份验证和加密安全机制。但是,在实际环境中实现远程管理时,应该实现这些安全机制。下一个什么?提供指向其他JMX技术文档的指针,这些文档展示了如何激活安全性。

此示例需要 Java SE 平台的第 6 版。要远程监控 Main JMX 代理,请按以下步骤操作:

  1. 如果您还没有这样做,请将 jmx_examples.zip保存到您的 work_dir 目录中。

  2. 在命令行或者终端使用下面的命令解压缩这个包:

    unzip jmx_examples.zip
    
  3. 在work_dir目录下编译例子中所有类:

    javac com/example/*.java
    
  4. 启动Main应用.确认显示Main正在等待一些事情发生.

    java -Dcom.sun.management.jmxremote.port=9999 \
         -Dcom.sun.management.jmxremote.authenticate=false \
         -Dcom.sun.management.jmxremote.ssl=false \
         com.example.Main
    
  5. 在同一台机器上打开一个新的命令行或者终端窗口,启动JConsole。新建连接对话框将会显示出来,列表中显示出可以连接的正在运行的JMX代理。

    jconsole
    
  6. 选择远程进程,然后在远程进程字段中键入以下内容:

    hostname:9999
    

    在该地址中,hostname是运行 "Main "应用程序的远程计算机的名称,9999 是开箱即用的 JMX 连接器所连接的端口号。

  7. 单击连接。

    将显示运行 Main 的 Java 虚拟机 (Java VM) 的当前活动摘要。

  8. 单击 MBeans 选项卡。

    该面板显示当前在远程 MBean 服务器中注册的所有 MBean。

  9. 在左侧框架中,展开 MBean 树中的 com.example 节点。

    您将看到由 Main创建并注册的示例 MBean Hello。如果单击 Hello,就会在 MBean 树中看到其相关的 Attributes 和 Operations 节点,尽管它运行在不同的机器上。

  10. 要关闭 JConsole,请选择连接 -> 退出。

创建自定义JMX客户端

本教程中的前几课向您展示了如何创建JMX技术MBean和MXBean,并将它们注册到JMX代理。但是,前面的所有示例都使用了现有的JMX客户机JConsole。本课将演示如何创建您自己的自定义JMX客户机。

客户机是自定义JMX客户机的一个示例,包含在jmx_examples.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类将创建JMXConnector实例,为此它需要一个JMXConnectorFactory和一个JMXServiceURL

创建通知侦听器

JMX客户机需要一个通知处理程序来侦听和处理可能由在JMX代理的MBean服务器中注册的MBean发送的任何通知。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类型的通知时,它将通过调用AttributeChangeNotification方法getAttributeName、getAttributeType、getNewValue和getOldValue,获得已更改的MBean属性的名称和类型,以及它的旧值和新值。

一个新的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);
...

如您所见,客户端定义了一个名为url的JMXServiceURL,它表示连接器客户端期望找到连接器服务器的位置。该URL允许连接器客户机从运行在本地主机端口9999上的RMI注册中心检索RMI连接器服务器存根jmxrmi,并连接到RMI连接器服务器。

这样标识RMI注册中心之后,就可以创建连接器客户端了。连接器客户机jmxc是接口JMXConnector的一个实例,由JMXConnectorFactory的connect()方法创建。在调用connect()方法时,传递参数url和空环境映射。

连接远程 MBean 服务器

有了RMI连接,JMX客户机必须连接到远程MBean服务器,这样它才能与远程JMX代理在其中注册的各种MBean进行交互。

...
        
MBeanServerConnection mbsc = 
    jmxc.getMBeanServerConnection();
                
... 

然后通过调用JMXConnector实例jmxc的getMBeanServerConnection()方法创建名为mbsc的MBeanServerConnection实例。

连接器客户机现在连接到由JMX代理创建的MBean服务器,并且可以注册MBean并对其执行操作,连接对两端保持完全透明。

首先,客户机定义了一些简单的操作来发现关于在代理的MBean服务器中找到的MBean的信息。

...
        
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的各种方法,以获得不同MBean操作的域、在MBean服务器中注册的MBean的数量以及它所发现的每个MBean的对象名称。

通过代理对远程MBean进行操作

客户端通过MBean服务器连接,通过创建MBean代理访问MBean服务器中的Hello 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代理允许您通过Java接口访问MBean,从而允许您对代理进行调用,而不必编写冗长的代码来访问远程MBean。这里通过调用javax.management.JMX类中的newMBeanProxy()方法创建Hello的MBean代理,并将MBean的MBeanServerConnection、对象名称、MBean接口的类名称和true传递给它,以表示代理必须作为notificationbroadcast。JMX客户机现在可以执行Hello定义的操作,就好像它们是本地注册的MBean的操作一样。JMX客户机还添加通知侦听器并更改MBean的CacheSize属性,以使其发送通知。

通过代理对远程MXBean进行操作

您可以以与创建MBean代理完全相同的方式为mxbean创建代理。

...
        
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());

...

如上所示,要为MXBean创建代理,只需调用JMX。newMXBeanProxy代替newMBeanProxy。MXBean代理mxbeanProxy允许客户端调用QueueSample MXBean的操作,就像它们是本地注册的MXBean的操作一样。

关闭连接

一旦JMX客户机获得了所需的所有信息并对远程JMX代理的MBean服务器中的MBean执行了所有必需的操作,就必须关闭连接。

运行Custom JMX Client示例

此示例需要 Java SE 平台的第 6 版。要使用自定义 JMX 客户端 Client远程监控 Main JMX 代理,请按照以下步骤操作:

  1. I如果您还没有这样做,请将 jmx_examples.zip保存到您的 work_dir 目录中。

  2. 在命令行或者终端使用下面的命令解压缩这个包:

    unzip jmx_examples.zip
    
  3. 在work_dir目录下编译例子中所有类:

    javac com/example/*.java
    
  4. 启动 "Main "应用程序,指定用于远程管理 "Main "的属性:会生成 "Main "正在等待某些事情发生的确认信息。

    java -Dcom.sun.management.jmxremote.port=9999 \
         -Dcom.sun.management.jmxremote.authenticate=false \
         -Dcom.sun.management.jmxremote.ssl=false \ 
         com.example.Main
    
  5. 在另一个终端窗口启动 "Client "应用程序:

    java com.example.Client
    

    显示已获得 MBeanServerConnection 的确认信息。

  6. 按 Enter 键。

    将显示由 Main启动的 MBean 服务器中注册的所有 MBean 所在的域。

  7. 再次按 Enter 键。

    显示在 MBean 服务器中注册的 MBean 数量以及所有这些 MBean 的对象名称。显示的 MBean 包括在 Java VM 中运行的所有标准平台 MXBean,以及由 "主 "在 MBean 服务器中注册的 "Hello "MBean 和 "QueueSampler "MXBean。

  8. 再次按 Enter 键。

    客户 "调用了 "Hello "MBean 的操作,结果如下:

    • 通知监听器被添加到 Client,以监听来自 Main 的通知。
    • 缓存大小 "属性的值从 200 变为 150。
    • 在启动 Main 的终端窗口中,会显示 CacheSize 属性更改的确认信息。
    • 在启动 Client 的终端窗口中,将显示来自 Main 的通知,告知 Client CacheSize 属性已更改。
    • 调用 Hello MBean 的 sayHello 操作。
    • 在启动 Main 的终端窗口中,会显示消息 “Hello world”。
    • 以 2 和 3 为参数,调用 Hello MBean 的 add 操作。结果将由 Client显示。
  9. 再次按回车键。

    客户 "调用了 "QueueSampler "MXBean 的操作,结果如下:

    • 显示QueueSampledateheadsize
    • 调用了 clearQueue 操作。
  10. 再次按 Enter 键。

    客户端 "将关闭与 MBean 服务器的连接,并显示确认信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值