使用 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
可以避免这个问题。
任何人都可以指导我在创建 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
可以避免这个问题。