zoukankan      html  css  js  c++  java
  • JMX笔记(一)

     上篇 JMX初体验 使用HtmlAdaptorServer提供的界面实现了调用MBean,除此之外,还可以使用rmi方式连接调用MBeanServer

     要连接,自然要有url:service:jmx:rmi://localhost:5000/jndi/rmi://localhost:6000/jmxrmi

     解释下:

    • service:jmx: 这个是JMX URL的标准前缀,所有的JMX URL都必须以该字符串开头。
    • rmi: 这个是connector server的传输协议,在这个url中是使用rmi来进行传输的。JSR 160规定了所有connector server都必须至少实现rmi传输,是否还支持其他的传输协议依赖于具体的实现。比如MX4J就支持soap、soap+ssl、hessian、burlap等等传输协议。
    • localhost:5000: 这个是connector server的IP和端口,这个端口可以称之为数据端口,该部分是一个可选项,如果省略的话,则connector server会随机任意选择一个可用的端口。
    • /jndi/rmi://localhost:6000/jmxrmi: 这个是connector server的路径,具体含义取决于前面的传输协议。比如该URL中这串字符串就代表着该connector server的stub是使用jndi api绑定在rmi://localhost:6000/jmxrmi这个地址。 这里的端口称之为通讯端口

    理清一个思路:MBean注册在MBeanServer上-》JMXConnectorServer 关联MBeanServer使用jndi绑定在rmiregistry的rmi://localhost:6000/jmxrmi地址,并使用5000端口传输数据-》rmiregistry监听6000端口

    先看下直接在jse下使用jmx

    服务器端:

         //在指定端口上启动远程对象注册服务程序,启用RMI,对应于 JAVA_HOME/bin/rmiregistry.exe
            LocateRegistry.createRegistry(9797);
            // MBeanServer mbs = MBeanServerFactory.createMBeanServer();//不能在jconsole中使用
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();//可在jconsole中使用
            //创建MBean
            HelloMBean mb = new Hello();
            //将MBean注册到MBeanServer中
            mbs.registerMBean(mb, new ObjectName("MyappMBean:name=controller"));
    
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9797/h-server");
            JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
            cs.start();

    客户端:

    @Test
        public  void jmxClient() throws IOException, MalformedObjectNameException {
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9797/h-server");
            JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
    MBeanServerConnection mbsc
    = jmxc.getMBeanServerConnection(); HelloMBean helloMb = JMX.newMBeanProxy(mbsc,new ObjectName( "MyappMBean:name=controller" ),HelloMBean.class ); System.out.println("client call:"+helloMb.sayHello()); jmxc.close(); }

     现在的项目都离不开spring了,如果jmx不能够整合到spring,总显得不伦不类,网上参考了许多就是没成功,总算是熟悉了直接使用jmx,摸着石头过河总算过来了

    server端配置

    为了避免不必要的麻烦,自己定义个MBeanServer,大部分情况下,我们的bean并不是实现MBean结尾的接口,普通bean更常见,所以我用了MBeanExporter的beans属性进行手动注册

    <bean id="mbServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
        <bean id="mbExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
        <property name="beans">
        <map>
          <entry key="MyappMBean:name=controller" value-ref="ffmMendService"/>
        </map>
        </property>
        <property name="server" ref="mbServer"/>
      </bean>
        <bean id="jmxConnectorServer" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry">
            <property name="objectName">
                <value>connector:name=rmi</value>
            </property>
            <property name="serviceUrl">
                <value>service:jmx:rmi:///jndi/rmi://127.0.0.1:9797/ffmservice</value>
            </property>
            <property name="environment">
                <props></props>
            </property>
            <property name="server" ref="mbServer"/>
        </bean>
        <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
            <property name="port">
                <value>9797</value>
            </property>
        </bean>

    注意说明:

    1. lazy-init="false",这里一定不能设置成true,否则客户端会报”MyappMBean:name=controller找不到“异常

    2. jmxConnectorServer需要设置environment属性,否则默认注入org.springframework.core.env.StandardEnvironment类型的evnironment,与ConnectorServerFactoryBean方法

    public void setEnvironment(Properties environment) {
    CollectionUtils.mergePropertiesIntoMap(environment, this.environment);
    }

    不匹配,报异常

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmxConnectorServer' defined in class path resource [spring-remote.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'org.springframework.core.env.StandardEnvironment' to required type 'java.util.Properties' for property 'environment'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.springframework.core.env.StandardEnvironment] to required type [java.util.Properties] for property 'environment': PropertyEditor [org.springframework.beans.propertyeditors.PropertiesEditor] returned inappropriate value of type [org.springframework.core.env.StandardEnvironment]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:548)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at mf.ffm.receiver.FFMReceiver.main(FFMReceiver.java:67)
    Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'org.springframework.core.env.StandardEnvironment' to required type 'java.util.Properties' for property 'environment'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.springframework.core.env.StandardEnvironment] to required type [java.util.Properties] for property 'environment': PropertyEditor [org.springframework.beans.propertyeditors.PropertiesEditor] returned inappropriate value of type [org.springframework.core.env.StandardEnvironment]
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:480)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:511)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:505)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1476)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1216)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    ... 11 more
    Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [org.springframework.core.env.StandardEnvironment] to required type [java.util.Properties] for property 'environment': PropertyEditor [org.springframework.beans.propertyeditors.PropertiesEditor] returned inappropriate value of type [org.springframework.core.env.StandardEnvironment]
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:283)
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:460)
    ... 17 more

    客户端配置:

    我不想在客户端定义服务接口,所以我使用了MBeanServerConnectionFactoryBean,等同于不用spring时

    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9797/h-server");
    JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
    MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

    获取了mbsc,而没用MBeanProxyFactoryBean

    <bean id="jmxSCFB" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
      <property name="connectOnStartup" value="false" />
      <property name="serviceUrl">
        <value>service:jmx:rmi:///jndi/rmi://127.0.0.1:9797/ffmservice</value>
      </property>
    </bean>

    参考文章

    1. jmx rmi 穿越防火墙问题及jmxmp的替代方案

    2. MXBean(示例,出错代码)

    3. Spring与JMX集成

    4. JMX API

    5. Chapter 20. JMX

  • 相关阅读:
    mvn编译
    国庆续写商品管理系统(二)
    Flask中多APP应用以及admin后台系统
    Bzoj3289 Mato的文件管理
    洛谷P2888 [USACO07NOV]牛栏Cow Hurdles
    POJ1988 Cube Stacking
    Bzoj3060 [Poi2012]Tour de Byteotia
    Bzoj3038 上帝造题的七分钟2 线段树
    Bzoj3038 上帝造题的七分钟2 并查集
    TYVJ1716 上帝造题的七分钟
  • 原文地址:https://www.cnblogs.com/yhzh/p/5139031.html
Copyright © 2011-2022 走看看