上篇 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"> <map> </map> </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找不到“异常
客户端配置:
我不想在客户端定义服务接口,所以我使用了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>
参考文章
3. Spring与JMX集成
4. JMX API
时间: 2024-11-09 13:52:25