`
淘气天空lc
  • 浏览: 47931 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JMX(二)----connectors

    博客分类:
  • java
阅读更多


     继续之前的,之前介绍了MBean server (http://90haofang-163-com.iteye.com/blog/1901416),这次主要简述如果使用JMX技术管理MBean,执行远程操作。通过RMI 作为connectors访问MBeans。这块需要实现服务端和客户端。

首先编写服务端:

1.创建MBean接口类SimpleStandardMBean

 

package git.git.tudou.manage.jmx.test.connectors;

/**
 * Date: 13-7-9
 * Time: 下午4:06
 */
public interface SimpleStandardMBean {
    //获取当前state 值
    public String getState();
    //修改state
    public void setState(String state);
    //获取状态改变次数
    public int getNuberChanges();
    //重置state和计数器 为初始值
    public void reset();

}
 然后编写MBean实现类SimpleStandard,名字必须是MBean的前缀,不然创建的MBean会出现问题。

 

package git.git.tudou.manage.jmx.test.connectors;

import javax.management.AttributeChangeNotification;
import javax.management.NotificationBroadcasterSupport;
import java.util.Date;

/**
 * standard MBean支持notification广播功能
 * Date: 13-7-9
 * Time: 下午4:05
 */
public class SimpleStandard  extends NotificationBroadcasterSupport implements SimpleStandardMBean{
    private  String state = "initial stae";
    private int nuberChanges=0;
    private int nbReset = 0;
    public String getState() {
        return this.state;
    }

    public void setState(String state) {
         this.state =state;
         //状态次数加1
         this.nuberChanges++;
    }

    public int getNuberChanges() {
        return this.nuberChanges;
    }
    public int getNbReset(){
        return this.nbReset;
    }

    public void reset() {
        state = "init state" ;
        this.nuberChanges = 0;
        nbReset++;
        /**
         * 属性变更通知
         * 参数说明
         * p1:指示通知的来源 在这里就是Hello MBean,用this替代
         * p2: 通知消息的序列号
         * p3:时间戳
         * p4:通知的内容
         * p5:变更的属性名
         * p6:变更属性的数据类型
         * p7: 属性的原值
         * p8:属性的新值
       */
        AttributeChangeNotification acn = new AttributeChangeNotification(
                this,nbReset,new Date().getTime(),"状态改变次数重置 ,state重置","Nbchanges","int",nuberChanges,0);
        sendNotification(acn);
    }
}
 该类继承了NotificationBroadcasterSupport ,实现通知功能在reset方法中发送了一个通知,说明nbchanges被重置,后面在客户端实现一个监听器,来接受通知。
服务端类Server
package git.git.tudou.manage.jmx.test.connectors;


import javax.management.*;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.rmi.registry.LocateRegistry;
import java.util.Scanner;

/**
 * MBean server
 * encode gbk
 * Date: 13-7-9
 * Time: 下午2:57
 */
public class Server {
    public static void main(String args[]){
        try{
            Scanner sc = new Scanner(System.in);
            LocateRegistry.createRegistry(9999);  //必须加上这句 不然就报错了 
           //创建一个MBean server
            MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
            //停顿一下
            sc.nextInt();
            //获得mBeanServer 默认域
            String domain = mBeanServer.getDefaultDomain();
            System.out.println("mBeanServer defualt domain:"+domain);
            sc.nextInt();
            //创建一个并且注册一个 SimpleStandard MBean
            String mbeanClassName = "git.git.tudou.manage.jmx.test.connectors.SimpleStandard";
            String mbeanObjectNameStr = domain+":type="+mbeanClassName+",name=1";
            //在MBean server创建一个bean
            ObjectName mBeanObjectName =  createSimpleMBean(mBeanServer,mbeanClassName,mbeanObjectNameStr);
            //输出MBean info
            printMBeanInfo(mBeanServer,mBeanObjectName,mbeanObjectNameStr);
            sc.nextInt();
            //通过MBean server管理MBean 类
            manageSimpleMBean(mBeanServer,mBeanObjectName,mbeanClassName);
            sc.nextInt();
            //创建RMI server 工程应用程序调用
            JMXServiceURL url = new JMXServiceURL(//url 绑定9999端口,这个可以自定义
            		      "service:jmx:rmi:///jndi/rmi://10.12.145.22:9999/server");
            //通过JMXConnectorServerFactory工厂 创建一个RMI连接实例
            JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url,null,mBeanServer);
            //启动RMI连接服务器
            connectorServer.start();
            System.out.println("RMI 服务已经启动..等待接受请求.");
            sc.nextInt();
            System.out.println("RMI服务关闭..");
            connectorServer.stop();
        }catch (Exception e){
            System.out.println("创建mbean server 异常"+e);
        }
    }
    //管理simpleMBean类
    public static void manageSimpleMBean(MBeanServer mbs,ObjectName mbeanObjectName,String mbeanClassName){
        try{
            //打印最开始的属性值
            printSimpleAttributes(mbs,mbeanObjectName);
            System.out.println("--------------------------------");
            System.out.println("修改state值为new state");
            Attribute attribute = new Attribute("State","new state");
            mbs.setAttribute(mbeanObjectName,attribute);
            System.out.println("--------------------------------");
            System.out.println("修改后的属性值:");
            printSimpleAttributes(mbs,mbeanObjectName);
            //调用reset方法
            mbs.invoke(mbeanObjectName,"reset",null,null);
            System.out.println("重置后所有属性值:");
            printSimpleAttributes(mbs,mbeanObjectName);

        }catch (Exception e){
            System.out.println("变更Simple Bean异常"+e);
        }

    }

    /**
     * 答应出MBean 的属性
     * @param mbs
     * @param mbeanObjectName
     */
    public static  void printSimpleAttributes(MBeanServer mbs,ObjectName mbeanObjectName){
        System.out.println("属性集合:");
        try{
            System.out.println("--------------------------------");
            System.out.println("SimpleMBean 属性值:");
            String state =(String)mbs.getAttribute(mbeanObjectName,"State");
            System.out.println("\tstate:"+state);
            int nuberChanges = (Integer)mbs.getAttribute(mbeanObjectName,"NuberChanges");
            System.out.println("\tnuberChanges:"+nuberChanges);
        }catch (Exception e){
            System.out.println("获取mbean属性异常"+e);
        }

    }
    /**
     * 打印MBean 信息
     * @param mbs
     * @param mbeanObjectName
     * @param mbeanClassName
     */
    public static void printMBeanInfo(MBeanServer mbs,ObjectName mbeanObjectName,String mbeanClassName){
        MBeanInfo info = null;
        try{
           info = mbs.getMBeanInfo(mbeanObjectName);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("获取"+mbeanClassName+"MBeanInfo 失败");
        }
        System.out.println("-------------------------------------------");
        System.out.println("类名:\t"+info.getClassName());
        System.out.println("类描述:\t"+info.getDescription());
        System.out.println("-------------------------------------------");
        System.out.println("属性:");
        MBeanAttributeInfo[] attributeInfos = info.getAttributes();
        for(MBeanAttributeInfo ainfo:attributeInfos){
            System.out.println("属性名:\t"+ainfo.getName());
            System.out.println("属性描述:\t"+ainfo.getDescription());
            System.out.println("属性数据类型\t"+ainfo.getType());
            System.out.println("属性是否可读\t"+ainfo.isReadable());
            System.out.println("属性是否可写\t"+ainfo.isWritable());
        }
        System.out.println("-------------------------------------------");
        System.out.println("构造方法:");
        MBeanConstructorInfo[] constructorInfos = info.getConstructors();
        for(MBeanConstructorInfo cinfo:constructorInfos){
            System.out.println("方法名:\t"+cinfo.getName());
            System.out.println("方法描述:"+cinfo.getDescription());
            System.out.println("参数个数:\t"+cinfo.getSignature().length);
        }
        System.out.println("-------------------------------------------");
        System.out.println("方法:");
        MBeanOperationInfo[]  operationInfos= info.getOperations();
        for(MBeanConstructorInfo oinfo:constructorInfos){
            System.out.println("方法名:\t"+oinfo.getName());
            System.out.println("方法描述:"+oinfo.getDescription());
            System.out.println("参数个数:\t"+oinfo.getSignature().length);
        }
        System.out.println("-------------------------------------------");
        System.out.println("通知:");
        MBeanNotificationInfo[] notificationInfos = info.getNotifications();
        for(MBeanNotificationInfo ninfo:notificationInfos){
            System.out.println("通知名:\t"+ninfo.getName());
            System.out.println("通知描述:"+ninfo.getDescription());
            String notificationType[] = ninfo.getNotifTypes();
            for(int i=0;i<notificationType.length;i++){
                System.out.println("type \t"+notificationType[i]);
            }
        }

    }
    public  static ObjectName createSimpleMBean(MBeanServer mbs,String mbeanClassName,String mbeanObjectNameStr){
        try{
            System.out.println("创建一个MBean "+mbeanClassName+"并在server 注册");
            ObjectName mbeanObjectName = ObjectName.getInstance(mbeanObjectNameStr);
            //MBean server创建一个bean
            mbs.createMBean(mbeanClassName,mbeanObjectName);
            return mbeanObjectName;
        }catch (Exception e){
            e.printStackTrace();
            System.exit(1);
        }
        return  null;
    }
}
 这里类首先创建一个MBserver.然后通过RMI发布出去。供远程应用程序调用,要注意的是
 LocateRegistry.createRegistry(9999); //这个很重要。不然直接无发绑定端口号,10.12.145.22是我的server运行的ip地址,应该替换为自己的server运行的ip地址。
创建mbean server 异常java.io.IOException: Cannot bind to URL [rmi://10.12.145.22:9999/server]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 10.12.145.22; nested exception is: 
	java.net.ConnectException: Connection refused: connect]
Disconnected from the target VM, address: '127.0.0.1:51094', transport: 'socket'
编写好服务端后,不着急写客户端首先可以用jconsole连接下这个服务地址 service:jmx:rmi:///jndi/rmi://10.12.145.22:9999/server 查看MBean,如图
 

 下图是我执行了操作reset,一共执行了2次,所以收到了两个通知,通知的发送定义在SimpleStandardMBean.reset方法中。

 接下自己编写客户端来管理MBean,通过RMI连接到MBserver,首先创建一个客户端监听器ClientListener,用来处理来自MBserver的通知
package git.git.tudou.manage.jmx.test.connectors;

import javax.management.Notification;
import javax.management.NotificationListener;

/**
 * 客户端监听通知监听器
 * Date: 13-7-9
 * Time: 下午6:54
 */
public class ClientListener implements NotificationListener {
    public void handleNotification(Notification notification, Object handback) {
        System.out.println("来自MBean server通知:"+notification.getMessage());
    }
}
ClientListener实现NotificationListener接口,实现handleNotification,用来处理来自客户端的通知。
接下来编写客户端Cient类
package git.git.tudou.manage.jmx.test.connectors;

import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * 创建一个RMI连接客户端
 * Date: 13-7-9
 * Time: 下午6:56
 */
public class Client {
    public static void main(String[] args) {
        try{
            Scanner sc = new Scanner(System.in);
            //通过rmi连接远程MBean
            JMXServiceURL url =  new JMXServiceURL("service:jmx:rmi:///jndi/rmi://10.12.145.22:9999/server");
            //获得远程JMX连接
            JMXConnector jmxConnector = JMXConnectorFactory.connect(url,null);
            ClientListener listener = new ClientListener();
            //获得MBserverConnection
            MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
            sc.nextInt();
            System.out.println("domain:");
            //获Mbean server所有连接
            String domains[] = mBeanServerConnection.getDomains();
            for(int i=0;i<domains.length;i++){
                System.out.println("domains["+i+"]="+domains[i]);
            }
            sc.nextInt();
            String domain=mBeanServerConnection.getDefaultDomain();
            String mbeanObjectNameStr = domain+":type=SimpleStandard,name=2";
            //新建一个ObjectName实例
            ObjectName mbeanObjectName = ObjectName.getInstance(mbeanObjectNameStr);
            //创建一个MBean
            mBeanServerConnection.createMBean("git.git.tudou.manage.jmx.test.connectors.SimpleStandard",mbeanObjectName,null,null);
            sc.nextInt();
            //获取所有的Object名字
            Set names = mBeanServerConnection.queryNames(null, null);
            for (Iterator i= names.iterator();i.hasNext();){
                System.out.println("ObjectName"+(ObjectName)i.next());
            }
            sc.nextInt();
            //管理MBean 首先变更属性
            System.out.println("state:"+(String)mBeanServerConnection.getAttribute(mbeanObjectName,"State"));
            mBeanServerConnection.setAttribute(mbeanObjectName, new Attribute("State", "new state2"));
            System.out.println("修改后 state:"+(String)mBeanServerConnection.getAttribute(mbeanObjectName,"State"));
            //方式二 直接通过MXBean代理
            /**
             * p1 MBean server连接
             * p2  MBean name
             * p3  接口类
             * p4  标记是否是NotificationBroadSupport
             */
            SimpleStandardMBean proxy = JMX.newMXBeanProxy(mBeanServerConnection,mbeanObjectName,SimpleStandardMBean.class,true);
            System.out.println("state 使用proxy:"+proxy.getState());
            //添加Notification监听器
            System.out.println("添加Notification监听器");
            mBeanServerConnection.addNotificationListener(mbeanObjectName,listener,null,null);
            //mBeanServerConnection 调用SimpleStandard reset方法
            mBeanServerConnection.invoke(mbeanObjectName,"reset",null,null);
            // proxy 调用reset方法
            System.out.println("proxy 调用reset方法");
            proxy.reset();
            sc.nextInt();
            Thread.sleep(2000);
            System.out.println("关闭连接。。。。");
            sc.nextInt();
            jmxConnector.close();
        }catch (Exception e){
            System.out.println("连接远程rmi异常,无法获得MBserver 连接"+e);
        }

    }
}
 改客户端类首先连接RMIserver 获得一个连接器,从连接器获得MBean server连接mBeanServerConnection,然后通过这个连接来管理远程MBean,可以通过它改变MBean属性,调用其方法
代码里面用两种方式获得MBean,一种是直接通过MBean创建,一种是proxy模式。通过MBean接口实例,调用MBean方法或者修改它的属性。
然后启动服务端,控制台输出:
1
mBeanServer defualt domain:DefaultDomain
1
创建一个MBean git.git.tudou.manage.jmx.test.connectors.SimpleStandard并在server 注册
-------------------------------------------
类名:	git.git.tudou.manage.jmx.test.connectors.SimpleStandard
类描述:	Information on the management interface of the MBean
-------------------------------------------
属性:
属性名:	State
属性描述:	Attribute exposed for management
属性数据类型	java.lang.String
属性是否可读	true
属性是否可写	true
属性名:	NuberChanges
属性描述:	Attribute exposed for management
属性数据类型	int
属性是否可读	true
属性是否可写	false
-------------------------------------------
构造方法:
方法名:	git.git.tudou.manage.jmx.test.connectors.SimpleStandard
方法描述:Public constructor of the MBean
参数个数:	0
-------------------------------------------
方法:
方法名:	git.git.tudou.manage.jmx.test.connectors.SimpleStandard
方法描述:Public constructor of the MBean
参数个数:	0
-------------------------------------------
通知:
1
属性集合:
--------------------------------
SimpleMBean 属性值:
	state:initial stae
	nuberChanges:0
--------------------------------
修改state值为new state
--------------------------------
修改后的属性值:
属性集合:
--------------------------------
SimpleMBean 属性值:
	state:new state
	nuberChanges:1
重置后所有属性值:
属性集合:
--------------------------------
SimpleMBean 属性值:
	state:init state
	nuberChanges:0
1
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
RMI 服务已经启动..等待接受请求.
 执行客户端main方法,输出:
1
domain:
domains[0]=JMImplementation
domains[1]=DefaultDomain
1
1
ObjectNameDefaultDomain:type=SimpleStandard,name=2
ObjectNameDefaultDomain:type=git.git.tudou.manage.jmx.test.connectors.SimpleStandard,name=1
ObjectNameJMImplementation:type=MBeanServerDelegate
1
state:initial stae
修改后 state:new state2
state 使用proxy:new state2
添加Notification监听器
proxy 调用reset方法
来自MBean server通知:状态改变次数重置 ,state重置
来自MBean server通知:状态改变次数重置 ,state重置
 可以最后两行客户端已经收到通话,说明客户端和服务进行了交互,能够通过RMI连接远程的MBean用于应用程序的管理,具体的业务实现类似,回头再写一个和spring整合的JMX。
 
 
 
 


 
 
 
  • 大小: 141.6 KB
  • 大小: 92.9 KB
  • 大小: 141.6 KB
分享到:
评论
3 楼 淘气天空lc 2014-02-10  
小鸟比比 写道
- -我没有思考 我错了 没事了

2 楼 小鸟比比 2014-01-24  
- -我没有思考 我错了 没事了
1 楼 小鸟比比 2014-01-24  
没有看到启动rmi服务器的提示 又不报错的情况怎么解决啊

相关推荐

    jmxri-1.2.1.jar+jmxtools-1.2.1.jar

    3. JMX Connectors:JMX连接器允许客户端与MBean服务器通信,支持RMI、HTTP、HTTPS等多种协议。 4. Notifications:MBeans可以通过发送通知来通告系统状态的变化,客户端可以订阅这些通知。 5. Attributes, ...

    cmdline-jmxclient-0.10.3.jar

    - **JMX Connectors**:提供了客户端与MBean Server之间的通信协议,如RMI/JRMP和JMXMP。 - **JMX URL**:用于指定连接到MBean Server的格式,如`service:jmx:rmi:///jndi/rmi://hostname:port/jmxrmi`。 总的来说...

    jmxtools-1.2.1.jar+jmxri-1.2.1.jar

    - **JMX Connectors**: 为客户端提供连接到JMX代理的接口,允许远程管理。 - **Security**: 支持JMX连接的安全性,包括认证和授权机制。 这两个jar文件通常一起使用,以实现完整的JMX远程管理功能。在部署Java...

    jmx-1_2_1-ri.zip jmx_remote-1_0_1_03-ri.zip jmx-1_1-mr-spec.zip

    这个版本可能包含了更新的连接器(Connectors)和协议支持,提高了安全性,增强了稳定性,并修复了一些已知问题。同样,它也包括了API库、示例和文档。 3. **jmx-1_1-mr-spec.zip**:这是JMX 1.1 Management ...

    jmx-1_2_1-ri.jar

    5. **Connectors**:JMX连接器允许远程访问MBean服务器,这样管理员就可以通过网络来监控和管理远程系统。 6. **Adapters**:适配器允许JMX与其他管理系统(如SNMP、WMI)集成,扩展了JMX的监控范围。 使用JMX,...

    jakarta-tomcat-connectors-1.2.15-src.zip

    【标题】"jakarta-tomcat-connectors-1.2.15-src.zip" 是一个包含Apache Tomcat连接器源代码的压缩包,主要用于帮助开发者深入理解Tomcat的工作原理,并进行自定义或扩展。 【描述】提到的"jakarta_tomcat_...

    jmx-1_1-ri.zip

    JMX的核心概念包括MBeans(Managed Beans)、代理(Agents)、服务提供者接口(Service Provider Interfaces,SPIs)和连接器(Connectors)。MBeans是Java对象,代表可管理的资源或服务,它们提供了暴露管理属性和...

    jmx-jvm配置

    4. **JMX Connectors**: 它们提供了访问MBean Server的通道,允许远程管理应用或JVM。 **JMX在JVM中的应用** 1. **JVM监控**: JMX可以通过MBeans提供JVM的性能指标,如内存使用情况、线程状态、类加载统计等。 2....

    JMX一步一步来,快速学会开发JMX应用

    JMX的核心概念包括MBeans(Managed Beans)、Servers、Agents以及Connectors,它们共同构成了一个灵活的管理架构。 1. **JMX简介** JMX的主要作用是让开发者能够创建和注册可管理的对象,即MBeans,它们代表了应用...

    jmx所需jar包

    5. **JMX Connectors**:它们是MBean Server和管理客户端之间的通信桥梁。JMX Connectors定义了多种协议,如RMI、HTTP/HTTPS等,以便于远程访问和管理。 6. **Adapters**:适配器允许JMX与非Java系统的交互,例如,...

    jmxtool.jar+jmxri.jar

    除此之外,jmxtools.jar还可能包含其他辅助类,帮助开发者在代码中实现JMX功能,如连接器(connectors)和其他管理工具。 描述中提到的"2个jar包maven仓库中缺少这个jar包"可能意味着在进行某些Java项目开发或构建...

    JAVA JMX 学习资料

    学习JMX,需要理解其基本概念,熟悉MBean的创建和注册,掌握如何使用JMX Connectors进行远程监控,以及如何利用JMX进行应用性能调优。对于开发者而言,JMX是提高应用可维护性和可管理性的重要工具。通过深入学习和...

    jmx资料

    3. JMX Connectors:JMX Connectors提供了MBean Server与外部世界的通信桥梁。它们定义了标准的协议和API,使得管理工具能够远程连接到MBean Server进行管理操作。 4. 管理工具:JMX支持多种类型的管理工具,包括...

    jmx相关jar包

    当你在应用程序中使用JMX特性时,`jmxri.jar` 提供了运行JMX代理(MBeans)和连接器(Connectors)所需的类和接口。它包含了服务器端的实现,比如MBeanServer,以及远程访问JMX代理的基础设施。 2. **jmxremote.jar...

    最简单JMX例子

    4. **管理接口暴露**:可能通过JMX的RMI或者JMX Connectors暴露MBeanServer,使得远程客户端能够访问。 5. **客户端工具**:使用JConsole、VisualVM或其他支持JMX的工具,连接到MBeanServer,查看和操作MBean。 ...

    JMXTools.jar和jmxri.jar下载

    5. **JMX Connectors**:提供客户端和MBean服务器之间的通信机制。JMX Connectors有多种协议实现,如RMI、HTTP/HTTPS、JNDI等,使得远程管理成为可能。 在实际应用中,JMX常用于监控和管理Java应用程序的性能、配置...

    JMX 远程服务器信息监控

    RMI允许跨网络调用对象方法,而JMX Connectors则是JMX和外部世界的桥梁,支持多种协议如JMX Remote Protocol,允许客户端通过网络连接到MBeanServer。 五、监控CPU利用率 在JMX中,可以使用MBeans获取操作系统级别...

    论文研究-基于JMX的网络管理系统.pdf

    - 连接器(Connectors):提供与外界通信的桥梁,支持远程访问MBean服务器。 - 协议适配器(Protocol Adaptors):将特定的协议转换为JMX协议,使得基于不同协议的系统可以访问JMX管理系统。 - 代理层(Proxy Layer...

    JMX开发入门

    **Protocol Adapters and Connectors** 用于JMX Agent与其他系统通信。适配器(Adapter)处理特定协议(如HTTP、SNMP),而连接器(Connector)则在Agent端和客户端都有相应组件,处理请求和响应。例如,RMI ...

Global site tag (gtag.js) - Google Analytics