4

在 Linux 机器上,我有一个现有的 3rd 方 Java 应用程序正在运行。我可以通过转到 /proc/PID/ 目录(内存、线程等)来了解应用程序的实时状态。但是,我想在同一台机器上运行一个单独的 Java 程序来做到这一点,而不使用 JConsole 或 VisualVM(如生产环境)。我搜索了 JMX 的主题。但是,它只返回关于它自己的程序的信息,而不是我试图监控的第 3 方应用程序。我对吗?有没有办法做到这一点(除了解析 /proc/PID/ 结果)?谢谢!

按照建议,我写了一个简单的程序来做本地监控。但是,我收到以下错误。任何想法?

    String hostName = "xx.xx.xx.xx";
    int portNum = xxxx;
    try {
        JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + portNum +  "/jmxrmi");
        JMXConnector c = JMXConnectorFactory.connect(u);
    }
    catch (Exception e) {
        e.printStackTrace();
    }

------Output------
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.NameNotFoundException: jmxrmi
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:338)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:207)
at test.main(test.java:57)
Caused by: javax.naming.NameNotFoundException: jmxrmi
at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:99)
at com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:185)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.management.remote.rmi.RMIConnector.findRMIServerJNDI(RMIConnector.java:1886)
at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1856)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:255)
... 3 more
4

3 回答 3

1

这正是 JMX 的用途。如果您运行的是 java 6 或更高版本,则每个 java 应用程序都会自动公开以供 JMX 代理监视和管理——如果您使用的是早期版本,则需要在启动应用程序时设置系统属性。

您甚至可以从另一台计算机上使用 JXM 远程监控它,它在后台使用 RMI。

一些资源:

于 2013-10-10T17:39:34.890 回答
0

对于我的第 3 方应用程序的本地监控,替换 JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + portNum + "/jmxrmi"); 通过 JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + portNum + "/server"); 解决了 javax.naming.NameNotFoundException: jmxrmi 的问题。内存和线程监控现在工作正常。感谢所有输入!

于 2013-10-11T03:06:21.410 回答
0

如果您在 Linux 中并且只需要 CPU、内存和线程,您可以使用Runtime.getRuntime().exec()将命令作为参数传递给 linux ps -p <pid> -o pid,nlwp,pcpu,pmem --sort pcpu。当然,您仍然需要解析输出。是这样的:

PID   NLWP  %CPU  %MEM
1765   52    4.6  11.3

NLWP进程中的线程数在哪里。

于 2013-10-10T17:40:01.130 回答