zoukankan      html  css  js  c++  java
  • 什么是MBeanServer

    什么是MBeanServer

    MBeanServer是一个包含所有注册MBean的仓库.它是JMX代理层的核心.JMX1.0规范提供一个接口叫 javax.management.MBeanServer. 所有管理的在MBean操作通过MBeanServer执行.使用MBeanServer实例,你能够管理所有MBean.每一个MBean具有一个唯一标志,叫ObjectName.

    什么是ObjectName

    ObjectName (javax.management.ObjectName)是一个类,唯一标志一个在MBeanServer的MBean.这个对象名称用于管理应用程序来标志MBean以便操作能够在适当的MBean上被调用.一个对象名称包含两部分.它们是

    1. 一个域名称

    2. 一个没有经过排序的一个或者多个关键属性集

    域名称是一个大小写敏感的字符串,这个字符串可以包括任何除[: , = * ?]之外的字符.

    域名称部分可以在一个对象名称里面忽略,如果这样的话,MBeanServer能够提供一个缺省的域名称.缺省的域名称将是DefaultDomain.

    关键属性集组织对象名称的第二部分.一个关键属性是一个名称-值对,名称不需对应MBean的任意属性或者操作.关键属性集必须包含至少一个关键属性.它可以包含任意数量的关键属性,这些关键属性的顺序没有意义.

    例如,如果我们描述一个海豚为MBean,那么一套对象名称可以是

    Animals:name=dolphin,kind=fish

    在这个对象名称中,字符串Animals 组成域名称, 关键属性集由两个关键属性描述:名称和类型,它们的值分别为dolphin和fish.

    通用的对象名称描述 如以下语法:

    [domain name]:property=value[,property=value]

    如果域名称被省略, MBeanServer将提供一个缺省的域名称叫[DefaultDomain].至少必须包含一个关键属性.任意数量的关键属性都可以添加进来.

    创建一个MBeanServer 实例

    MBeanServer实例能够用MBeanServerFactory类提供的方法获取.MBeanServerFactory类提供了以下方法来获取MBeanServer实例:

    public static MBeanServer createMBeanServer()

    public static MBeanServer createMBeanServer(String domain)

    public static MBeanServer newMBeanServer()

    public static MBeanServer newMBeanServer(String domain)

    在以上声明的方法中,字符串domain描述对象名称(object name)的域部分.createMBeanServer方法和newMBeanServer方法返回一个MBeanServer实例.这两个方法的区别在于createMBeanServer返回一个MBeanServer实例并且保存这个实例的关联以便能够用findMBeanServer方法访问这个实例.newMBeanServer方法将不保存这个被创建的MBeanServer的实例的任何关联.

    如果使用一个变量的构造器创建一个MBeanServer实例,这个字符串变量将作为创建的MBeanServer实例的域名.如果没有变量的构造器被用来创建MBeanServer实例,那么域名称将用字符串DefaultDomain.

    查找一个MBeanServer 实例

    MBeanServerFactory类提供一个方法叫findMBeanServer用于一个指定MBeanServer实例或者所有MBeanServer实例能够被获取的情况.这个方法的声明为

    public static ArrayList findMBeanServer(String id) 这里字符串id表明 MBeanServer 的标志符. 如果这个字符串为null, 那么返回所有在此JVM中注册的 MBeanServer . 如果想返回相应指定的MBeanServer实例,那么必须提供这个MBeanServer实例的相应字符串id. 这个字符串id能够通过 MBeanServerDelegateMBean 的StringId 属性获取.

    MBeanServerDelegate MBean无论一个MBeanServer何时被初始化,MBeanServerDelegate类被作为一个MBean注册,

    名字为JMImplementation:type=MBeanServerDelegate. 这个MBean提供关于这个 MBean 服务器的信息.

    MBeanServerDelegate MBean 具有七个只读属性,名字为 MBeanServerId, SpecificationName, SpecificationVersion, SpecificationVendor, ImplementationName, ImplementationVersion 和ImplementationVendor.

    XMOJO项目5 的MBeanServerDelegate MBean 提供的属性的缺省值为:

    属性名称 属性值
    SpecificationVersion 1.0, Final Release
    SpecificationVendor Sun Microsystems Inc.
    ImplementationVersion 5
    ImplementationVendor XMOJO (sponsered by AdventNet Inc.)
    ImplementationName The XMOJO Project
    MBeanServerId _1
    SpecificationName Java Management Extensions Instrumentation and Agent Specification

    MBeanServerDelegate MBean 响应 MBeanServer 发出的广播消息.无论何时一个MBean被注册或者被注销,

    MBeanServerDelegate MBean 广播类型分别为jmx.mbean.created和jmx.mbean.deleted的消息到所有注册的监听器.

    需要记住的几点

    1. MBeanServer 维护一个注册的MBean.每一个MBean由一个唯一命名的模式叫对象名称(object name)区分.

    2. MBeanServer 实例能够用MBeanServerFactory类的静态方法获得.

    3. MBeanServerDelegate MBean 是一个MBeanServer的描述,也是MBeanServer发出消息的广播者.

    ====================================================================

    Server端程序范例:
     
    1. MBean接口
    这是一个应用程序将要向外暴露的接口,在该接口中需要定义要公布的所有函数。
    其中,如果存在一对对应的get方法和set方法,那么就默认有一个属性,且熟悉的名字就是get方法名字中get后面的部分。
    包含在MBean中方法都将是可以被管理的。MBean起名是有规范的,就是原类名后加上MBean字样。
    package com.dxz.study;
    
    public interface HelloWorldMBean {
        public String getName();          
        public void setName(String name);      
        public void printHello();         
        public void printHello(String whoName);  
    }
    2. 被管理的类
    被管理的类需要实现相应的MBean接口,通过MBean接口中的方法来被管理。
    package com.dxz.study;
    
    public class HelloWorld implements HelloWorldMBean {
    
        private String name;
        public String getName() {
            // TODO Auto-generated method stub
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
    
        }
    
        public void printHello() {
            System.out.println("Hello World, " + name);    
    
        }
    
        public void printHello(String whoName) {
              System.out.println("Hello , " + whoName);      
    
        }
    
    }
    3. 创建一个Agent类
    Agent其实实现的是类似于Server的功能,他负责把JMX服务绑定到相应的URL,并将我们上面创建的被管理的类绑定到其中,使得外部可以访问。
    package com.dxz.study;
    
    import java.io.IOException;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.registry.Registry;
    
    import javax.management.InstanceAlreadyExistsException;
    import javax.management.MBeanRegistrationException;
    import javax.management.MBeanServer;
    import javax.management.MBeanServerFactory;
    import javax.management.MalformedObjectNameException;
    import javax.management.NotCompliantMBeanException;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    import com.sun.jdmk.comm.HtmlAdaptorServer; 
    
    public class HelloWorldAgent {
        public static void main(String[] args) throws MalformedObjectNameException, NullPointerException,
                InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, IOException {
    
            int rmiPort = 1099;
            String jmxServerName = "TestJMXServer";
    
            // jdkfolder/bin/rmiregistry.exe 9999
            Registry registry = LocateRegistry.createRegistry(rmiPort);
    
            MBeanServer mbs = MBeanServerFactory.createMBeanServer(jmxServerName);
            // MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    
            HtmlAdaptorServer adapter = new HtmlAdaptorServer();
            ObjectName adapterName;
            adapterName = new ObjectName(jmxServerName + ":name=" + "htmladapter");
            adapter.setPort(8082);
            adapter.start();
            mbs.registerMBean(adapter, adapterName);
    
            ObjectName objName = new ObjectName(jmxServerName + ":name=" + "HelloWorld");
            mbs.registerMBean(new HelloWorld(), objName);
    
            JMXServiceURL url = new JMXServiceURL(
                    "service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + jmxServerName);
            System.out.println("JMXServiceURL: " + url.toString());
            JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
            jmxConnServer.start();
    
        }
    }
    pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.dxz</groupId>
      <artifactId>study</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>study</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
         <groupId>org.glassfish.external</groupId>
        <artifactId>opendmk_jdmkrt_jar</artifactId>
        <version>1.0-b01-ea</version>
        </dependency>
      </dependencies>
    </project>
    说明:
    1. Agent实现中的35行到40行为MBeanServer添加了一个htmladapter,这样我们就可以通过网页的方式来进行管理。
     比如说上面我们实行的Agent,我们就可以通过http://localhost:8082来对程序进行管理。这里的8082就是htmladapter中设置的端口。
     
    通过我们设定的MBean名字点击去,就可以进一步来管理我们的MBean
     
     
     从这张图我们可以看出,我们可以直接从网页上面来改动Name的值,并且也可以直接通过点击来调用相应的方法:printHello
     
     
     2. 如果大家在尝试写Agent程序时出现connection refused的异常的时候,不用怕,赶紧检查一下你的程序中是不是有这句话:
       Registry registry = LocateRegistry.createRegistry(rmiPort);
       LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry
       或者,你也可以运行  jdkfolder/bin/rmiregistry.exe 9999
       其中jdkfolder是你的jdk的安装目录,9999是你要绑定的端口
       运行上面的命令和你在代码中添加上面那行code是一样的效果
       
     3. Agent的实现中的32行和33行是两种获取MBeanServer的方式。
        MBeanServer mbs = MBeanServerFactory.createMBeanServer(jmxServerName);
        这种方式主要用于JDK1.5以前
      MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
       这种方式是JDK1.5引入的。
       安全起见,当大家不能确定以后部署的机器上面安装的JDK是1.5以上的版本时,建议按照第一种方式。
       
     4. 绑定需要被管理的类
        ObjectName objName = new ObjectName(jmxServerName + ":name=" + "HelloWorld");
      mbs.registerMBean(new HelloWorld(), objName);
      这里我们可以看到,首先要给被绑定的类起一个名字,然后把这个名字和被管理的类一起注册到MBeanServer当中。
      
    5. 将服务绑定到固定的URL上
      JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + jmxServerName);
      JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
      jmxConnServer.start();
      在start方法被调用后,服务就已经发布成功,我们就可以通过页面或者其他的方式来访问服务
  • 相关阅读:
    运算符优先级
    Tips—查询某结构体
    在线词典--(一、流程分析)
    数据库—SQLite3
    回调函数(转载)
    UNIX域套接字
    进程间通信小结
    HDU_oj_2027 统计元音
    HDU_oj_2026 首字母变大写
    HDU_oj_2025 查找最大字母
  • 原文地址:https://www.cnblogs.com/duanxz/p/4495518.html
Copyright © 2011-2022 走看看