上篇 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

JMX笔记(一)的更多相关文章

  1. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  2. JMX学习笔记(一)-MBean

    JMX学习笔记(一)-MBean 标签: jmxstringjavainterfaceexceptionclass 2010-12-07 22:20 15360人阅读 评论(5) 收藏 举报  分类: ...

  3. ActiveMQ笔记(5):JMX监控

    系统上线运行后,及时监控报警是很必要的手段,对于ActiveMQ而言,主要监控的指标有:MQ本身的健康状况.每个队列的生产者数量.消费者数量.队列的当前消息数等. ActiveMQ支持JMX监控,使用 ...

  4. JMX学习笔记(三)-MXBean

    在MBean中有只要遵循以下两个规则,我们就可以在jconsole中动态的改变MBean中的属性值 1. JMX中要定义接口必须以xxxMBean的规范定义 2. 得有类实现xxxMBean接口 例如 ...

  5. Java_jvisualvm使用JMX连接远程机器(实践)

    https://my.oschina.net/heroShane/blog/196227 一.启动普通的jar程序 1.执行foo.jar启动命令 java -Dcom.sun.management. ...

  6. Java学习笔记之JNDI(六)

    JNDI 是什么 JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,不少专家认为,没有透彻理解JNDI的 ...

  7. Spring Batch学习笔记二

    此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch的架构 一个Batch Job是指一系列有序的Step的集合,它们作为预定义流程的一部分而被执行: Step代表一个自 ...

  8. 28.zookeeper单机(Standalones模式)和集群搭建笔记

    zookeeper单机(Standalones模式)和集群搭建: 前奏: (1).zookeeper也可以在windows下使用,和linux一样可以单机也可以集群,具体就是解压zookeeper-3 ...

  9. ELK笔记

    ELK笔记 ELKStack高级实战培训http://files.cnblogs.com/files/MYSQLZOUQI/ELKStack%E9%AB%98%E7%BA%A7%E5%AE%9E%E6 ...

随机推荐

  1. find in linux

    find命令的作用是在目录中根据文件名搜索文件find 列出当前目录及其子目录的所有文件和文件夹的完整路径.find -name Help.java 在当前目录及其子目录中搜索文件名为Help.jav ...

  2. 第二百五十八天 how can I 坚持

    装虚拟机了.CentOs,32位,这电脑装4台能不能带起来啊. 早上,流鼻血了,不知道咋回事.太干了... 明天得早起会,得利索着点,不能托托拉拉的. 还有,今天又忘带钥匙了.悲剧. 睡觉.hadoo ...

  3. Apache Spark Streaming的适用场景

    使用场景: Spark Streaming 适合需要历史数据和实时数据结合进行分析的应用场景,对于实时性要求不是特别高的场景也能够胜任.

  4. Storm ui 展示字段说明

    1.Storm ui 首页 主要分为4块: Cluster Summary,Topology summary,Supervisor summary,Nimbus Configuration,如下图所示 ...

  5. CodeForces 689A Mike and Cellphone (模拟+水题)

    Mike and Cellphone 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/E Description While sw ...

  6. Codeforces Round #271 (Div. 2) D. Flowers (递推)

    题目链接:http://codeforces.com/problemset/problem/474/D 用RW组成字符串,要求w的个数要k个连续出现,R任意,问字符串长度为[a, b]时,字符串的种类 ...

  7. CodeForces 732D Exams (二分)

    题意:某人要考试,有n天考m个科目,然后有m个科目要考试的时间和要复习多少天才能做,问你他最早考完所有科目是什么时间. 析:二分答案,然后在判断时,直接就是倒着判,很明显后出来的优先,也就是一个栈. ...

  8. CoordinatorLayout的简单应用(材料设计新控件)

    CoordinatorLayout字面意思为:协调布局,一般作为根布局使用.关于这个布局,记录一下两个用法,备忘. 一.配合 FloatingActionBar 使用 <?xml version ...

  9. TCP四种定时器--学习笔记

    TCP使用四种定时器: 重传定时器(Retransmission Timer).坚持定时器(Persistent Timer).保活定时器(Keeplive Timer).时间等待定时器(Time_W ...

  10. 自己写一个jQuery垂直滚动栏插件(panel)

    html中原生的滚动栏比較难看,所以有些站点,会自己实现滚动栏,导航站点hao123在一个側栏中,就自己定义了垂直滚动栏,效果比較好看,截图例如以下: watermark/2/text/aHR0cDo ...