使用 JMX 获取远程 JVM 属性

Getting remote JVM properties using JMX

任何人都可以指导我在创建 JVM 连接后如何获取 JVM 的属性吗?我需要以编程方式获取这些信息。 我在没有得到任何提示的情况下搜索了这个。 如有任何想法,我们将不胜感激。

我认为最小的例子应该是这样的:

public class JMXSystemProperties {

public static void main(String[] args) throws Exception {
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi");
    JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

    MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
    TabularDataSupport data = (TabularDataSupport) mbsc.getAttribute(new ObjectName("java.lang:type=Runtime"), "SystemProperties");
    for (Entry<Object, Object> entry : data.entrySet()) {
        CompositeDataSupport value = (CompositeDataSupport) entry.getValue();
        System.out.println(entry.getKey() + " = " + value.values());
    }
}
}

您仍然可以使用jvisualvm查看所有数据是否正确。

您可以将 url 中的 localhost 和端口 9004 替换为更适合您的服务器和端口。

谢谢

看看JMX tutorial and examples

你想要的属性可以从RuntimeMXBean获得。

提示:连接到 JMX 后,在我看来有一个标准的 MXBean 接口实现了 java.lang.management.RuntimeMXBean。相关 ObjectName 应该是:

ObjectName objName = new ObjectName("java.lang:type=Runtime");

获取代理实例对象是这样的:

RuntimeMXBean runtimeMXBean = JMX.newMXBeanProxy(mbeanServer, objName, RuntimeMXBean.class, true);

也许这会对其他人有所帮助。

N.B。如果有人可以提供 link 文档,说明支持 JMX 的系统需要 RuntimeMXBean 接口,那将是受欢迎的。

None 已经提供的答案确实对我有用。我遇到的一些问题:

  • 接受的答案只不过是指向文档的指针,没有错,但对解决所有细节没有真正的帮助。
  • TabularDataSupport 如果您只想获取系统属性的映射,则需要解压一些 PITA。 (键将包装在列表中,必须解压缩;并且 TabularDataSupport Map 的 'values' 实际上不是您想要的值......但仍然包装在一个 'CompositeDataSupport' 对象中,该对象也有进一步解压。)。
  • 使用 JMX.newMXBeanProxy 看起来很有希望避免所有这些拆包。但是尽管它编译...在运行时,我发现代理的 getSystemProperties 的结果实际上根本没有正确解包。它仍然是一个 TabularDataSupport 对象(是的,尽管它的编译时类型说它应该是一个 Map<String,String>,但实际上它不是)。

所以这里有一些东西实际上 确实 对我有用,所有这些陷阱都解决了,所以它给系统属性就像你一样 Map<String,String>' d可能想要。

package example;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.Map;
import java.util.Map.Entry;

import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class GetJmxSystemProps {

    public static void main(String[] args) throws Exception {
        JMXServiceURL serviceUrl =  new JMXServiceURL("service:jmx:rmi://localhost:9111/jndi/rmi://localhost:9111/jmxrmi");
        JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
        MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
        RuntimeMXBean proxy = ManagementFactory.getPlatformMXBean(connection, RuntimeMXBean.class);
        Map<String, String> sysprops = proxy.getSystemProperties();
        for (Entry<String, String> e : sysprops.entrySet()) {
            System.out.println(e.getKey()+"="+e.getValue());
        }
    }
}

总结:这里的关键点是使用 JMX.newMXBeanProxy 获取类型 RuntimeMXBean 的 bean 是错误的,并且不会将 TabularDataSupport 对象解压为 Map<String,String> 正确。使用方法 ManagementFactory.getPlatformMXBean 可以避免这个问题。