如何使用JMX连接到本地主机jvm上的java程序?

如何使用JMX连接到本地主机jvm上的java程序?,java,localhost,rmi,jmx,jconsole,Java,Localhost,Rmi,Jmx,Jconsole,我应该使用JMX连接到本地主机jvm上的java程序。换句话说,我想开发一个JMX客户机来在本地主机上配置java程序 不要推荐使用JConsole!JConsole不适合,因为它是通用的JMX客户端,对主程序性能有负面影响 oracle站点上的示例使用RMIConnector和host:port参数,但我不知道: 应该在哪里设置jmx端口 JConsole有一个通过PID连接到java进程的选项。但我在JMXAPI中找不到任何将PID作为输入参数的方法 我们使用以下类似的方式以编程方式连接到

我应该使用JMX连接到本地主机jvm上的java程序。换句话说,我想开发一个JMX客户机来在本地主机上配置java程序

  • 不要推荐使用JConsole!JConsole不适合,因为它是通用的JMX客户端,对主程序性能有负面影响

  • oracle站点上的示例使用RMIConnector和host:port参数,但我不知道: 应该在哪里设置jmx端口

  • JConsole有一个通过PID连接到java进程的选项。但我在JMXAPI中找不到任何将PID作为输入参数的方法


我们使用以下类似的方式以编程方式连接到我们的JMX服务器。您应该使用以下参数运行服务器:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=A.B.C.D
要绑定到特定地址,您需要添加以下VM参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=A.B.C.D
然后,您可以使用JMX客户端代码连接到服务器,如下所示:

String host = "localhost";  // or some A.B.C.D
int port = 1234;
String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
JMXServiceURL serviceUrl = new JMXServiceURL(url);
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
try {
   MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();
   // now query to get the beans or whatever
   Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);
   ...
} finally {
   jmxConnector.close();
}
它也有一个客户端接口,但目前没有任何通过PID查找进程的机制——只支持主机/端口组合(在2012年6月); jvmList=新的JVMListManager(); vm=jvmList.listActiveVM(); for(VirtualMachineDescriptor vmD:vm) { 尝试 { //importFrom获取进程ID并以字符串格式返回服务url 字符串ServiceUrl=ConnectorAddressLink.importFrom(Integer.parseInt(vmD.id().trim()); JMXServiceURL JMXServiceURL=新的JMXServiceURL(ServiceUrl); jmxConnector=JMXConnectorFactory.connect(jmxServiceUrl,null); con=jmxConnector.getMBeanServerConnection(); CompilationMXBean compMXBean=ManagementFactory.newPlatformMXBeanProxy(con ,ManagementFactory.COMPILATION\u MXBEAN\u NAME ,compilementmxbean.class); }捕获(例外e) { //做点什么 } } 受保护列表listActiveVM(){ List vm=VirtualMachine.List(); 返回虚拟机; } 这要求您在JVM启动时为尝试读取的进程使用jmxremote参数。
不必在启动时传递jmxremote参数即可完成此操作。您必须使用附加api(仅适用于使用Java 6及更高版本的程序。

为了澄清,如果您只对获取本地JMX统计数据感兴趣,则不需要使用远程api。只需使用
Java.lang.management.ManagementFactory

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
memoryMXBean.getHeapMemoryUsage().getMax();
...

List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans();
...
MemoryMXBean MemoryMXBean=ManagementFactory.getMemoryMXBean();
memoryMXBean.getHeapMemoryUsage().getMax();
...
List bean=ManagementFactory.getMemoryPoolMXBeans();
...
最简单的意思是:

import javax.management.Attribute;
import javax.management.AttributeList;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

// set a self JMX connection
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// set the object name(s) you are willing to query, here a CAMEL JMX object
ObjectName objn = new ObjectName("org.apache.camel:context=*,type=routes,name=\"route*\"");
Set<ObjectName> objectInstanceNames = mBeanServer.queryNames(objn, null);
for (ObjectName on : objectInstanceNames) {
    // query a number of attributes at once
    AttributeList attrs = mBeanServer.getAttributes(on, new String[] {"ExchangesCompleted","ExchangesFailed"});
    // process attribute values (beware of nulls...)
    // ... attrs.get(0) ... attrs.get(1) ...
}
import javax.management.Attribute;
导入javax.management.AttributeList;
导入java.lang.management.ManagementFactory;
导入javax.management.MBeanServer;
导入javax.management.ObjectName;
//设置一个自JMX连接
MBeanServer MBeanServer=ManagementFactory.getPlatformMBeanServer();
//设置您想要查询的对象名,这里是一个CAMEL JMX对象
ObjectName objn=newobjectname(“org.apache.camel:context=*,type=routes,name=\“route*\”);
Set objectInstanceNames=mBeanServer.queryNames(objn,null);
for(上的ObjectName:objectInstanceNames){
//一次查询多个属性
AttributeList attrs=mBeanServer.getAttributes(打开,新字符串[]{“ExchangesCompleted”,“ExchangesFailed”});
//进程属性值(注意空值…)
//…属性获取(0)…属性获取(1)。。。
}

这是如何使用PID将JMX连接到Java程序的方法(对于版本,主程序和JMX客户端都是独立程序(Java SE)。另请参见感谢Gray!您(或其他人)能否回答我的第二个问题(使用PID连接本地JMX)?如果由于某种原因,ConnectorAddress为null,则可以尝试以友好方式加载代理。请参阅第行中的编译问题:jmxConnector.close();
import javax.management.Attribute;
import javax.management.AttributeList;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

// set a self JMX connection
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// set the object name(s) you are willing to query, here a CAMEL JMX object
ObjectName objn = new ObjectName("org.apache.camel:context=*,type=routes,name=\"route*\"");
Set<ObjectName> objectInstanceNames = mBeanServer.queryNames(objn, null);
for (ObjectName on : objectInstanceNames) {
    // query a number of attributes at once
    AttributeList attrs = mBeanServer.getAttributes(on, new String[] {"ExchangesCompleted","ExchangesFailed"});
    // process attribute values (beware of nulls...)
    // ... attrs.get(0) ... attrs.get(1) ...
}
import sun.management.ConnectorAddressLink;
import javax.management.*;

public static MBeanServerConnection getLocalJavaProcessMBeanServer(int javaProcessPID) throws IOException {
    String address = ConnectorAddressLink.importFrom(javaProcessPID);
    JMXServiceURL jmxUrl = new JMXServiceURL(address);
    return JMXConnectorFactory.connect(jmxUrl).getMBeanServerConnection();
}