本地JMX客户端无法找到已注册MBean问题求助
问题原因
你第二个应用里ManagementFactory.getPlatformMBeanServer()获取的是当前客户端进程自己的JVM内置MBeanServer,而第一个应用的MBean是注册在它自身JVM的MBeanServer里的——两个应用是完全独立的JVM进程,自然看不到对方的MBean。
解决步骤
要跨进程访问JMX MBean,必须用JMX远程连接,分两步操作:
1. 给第一个应用添加JMX远程启动参数
启动第一个应用时,添加以下JVM参数,开启远程JMX服务:
-Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost
port:指定JMX远程连接的端口rmi.port:RMI通信端口,和JMX端口保持一致可避免复杂配置authenticate=false和ssl=false:关闭认证和SSL(仅用于测试,生产环境必须开启安全验证)java.rmi.server.hostname:指定RMI服务绑定的主机名,本地测试用localhost即可
2. 修改客户端代码,连接远程MBeanServer
替换客户端里获取MBeanServerConnection的方式,改用JMXConnector连接第一个应用的远程JMX服务,修正后的代码如下:
import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.management.openmbean.CompositeData; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.io.IOException; import java.util.Arrays; public class JMXClient { public static void main(String[] args) { JMXConnector connector = null; try { // 构造远程JMX服务URL,端口和第一个应用的启动参数一致 JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi" ); // 连接远程MBeanServer connector = JMXConnectorFactory.connect(url); javax.management.MBeanServerConnection mbs = connector.getMBeanServerConnection(); // 打印所有域,现在应该能看到cl.maraneda.jmx Arrays.stream(mbs.getDomains()).forEach(System.out::println); ObjectName name = new ObjectName("cl.maraneda.jmx:type=QueueSampler"); CompositeData queueSample = (CompositeData) mbs.getAttribute(name, "QueueSample"); int size = (Integer) queueSample.get("size"); System.out.println("获取到的队列大小是 " + size); } catch (MalformedObjectNameException | InstanceNotFoundException | AttributeNotFoundException | ReflectionException | MBeanException | IOException e) { e.printStackTrace(); } finally { if (connector != null) { try { connector.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
验证步骤
- 先启动带上述JVM参数的第一个应用
- 再运行修改后的客户端程序,就能成功获取到第一个应用里注册的MBean数据了
内容的提问来源于stack exchange,提问作者mrcoar
相关产品推荐
相关产品推荐

