java - 如何通过java代码设置JMX远程端口系统环境参数进行远程监控?

标签 java rmi jmx

我有一个程序需要动态地(即在运行时)打开一个可用的套接字并在其上启动一个 JMX 代理。此 JMX 参数是在 Java 代码中设置的,而不是通过命令行设置的。这很好用。此后需要通过 Java Visual VM 进行监控(即发出 JMX 命令等) 远程

程序中的 RMI 服务器代理是开箱即用的管理方式,描述如下: http://download.oracle.com/javase/6/docs/technotes/guides/management/agent.html

我的问题可以概括为: 这样的命令行属性如何设置为系统级别 通过 Java 代码,以便可以使用远程分析??

-Dcom.sun.management.jmxremote.port=1234

如果通过命令行设置“jmxremote.port”等参数, 远程监控工作正常。我正在尝试通过 Java 找到一种方法来做到这一点 而不是通过命令行。

程序无法通过命令行指定端口,因为必须在运行时确定新的可用端口。

进程需要远程监控,本地运行良好。 如果未在命令行指定以下参数,则 Java Visual VM 不会连接到该进程。

-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=10.0.0.128

我试过了。

System.setProperty("com.sun.management.jmxremote.port",Integer.toString(port));

这是启动 JMXConnectorServer 之前程序中要做的第一件事。不幸的是,它不被认可。只有运行时属性(即通过命令行指定)才能被 Java Visual VM 识别为 JMX 连接。

还遇到了可以从 java 集合类中提取属性但无法达到如何跟踪属性 "com.sun.management.jmxremote.port="

public static void setEnv(Map<String, String> newenv) throws Exception {
  Class[] classes = Collections.class.getDeclaredClasses();
  Map<String, String> env = System.getenv();

  for(Class cl : classes) {

    if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {

      Field field = cl.getDeclaredField("m");
      field.setAccessible(true);

      Object obj = field.get(env);
      Map<String, String> map = (Map<String, String>) obj;

      //map.clear();
      map.putAll(newenv);
    }
  }
}

任何帮助将不胜感激!

最佳答案

kbec 的回答指明了方向,但对我不起作用 - 但是通过查看 this post我能够对其进行修改并获得有效的解决方案。

public static String loadJMXAgent(int port) throws IOException,
        AttachNotSupportedException, AgentLoadException,
        AgentInitializationException {
    String name = ManagementFactory.getRuntimeMXBean().getName();
    VirtualMachine vm = VirtualMachine.attach(name.substring(0,
            name.indexOf('@')));

    String lca = vm.getAgentProperties().getProperty(
            "com.sun.management.jmxremote.localConnectorAddress");
    if (lca == null) {
        Path p = Paths.get(System.getProperty("java.home")).normalize();
        if (!"jre".equals(p.getName(p.getNameCount() - 1).toString()
                .toLowerCase())) {
            p = p.resolve("jre");
        }
        File f = p.resolve("lib").resolve("management-agent.jar").toFile();
        if (!f.exists()) {
            throw new IOException("Management agent not found");
        }
        String options = String.format("com.sun.management.jmxremote.port=%d, " +
                "com.sun.management.jmxremote.authenticate=false, " +
                "com.sun.management.jmxremote.ssl=false", port);
        vm.loadAgent(f.getCanonicalPath(), options);
        lca = vm.getAgentProperties().getProperty(
                "com.sun.management.jmxremote.localConnectorAddress");
    }
    vm.detach();
    return lca;
}

这在 Eclipse 中有效,但是让它在命令行中工作是另一回事 - 这里有一些关于此的讨论 Why does using the Java Attach API fail on linux? (even though maven build completes) 但我发现将 $JAVA_HOME/lib/tools.jar 添加到我的类路径中解决了这个问题。

关于java - 如何通过java代码设置JMX远程端口系统环境参数进行远程监控?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7276881/

相关文章:

java - JAX-RS 中等效的 Servlet init() 方法

java - 有没有一种方法可以对数据集使用compareTo() 方法,而无需迭代该集合的每个元素?

java - 同步使对象锁定

java - RMI 服务器连接拒绝主机 : ############ ; nested exception is: java.net.ConnectException:连接被拒绝:连接

java - 读取 XML 并创建多个表

java - 使用代码模型扩展 AbstractEntity<MyClass>

java - 无法与远程服务器上的 RMI 注册表建立连接

java - 如果服务器崩溃,如何以及何时从 RMI 注册表中删除名称?

java - 在本地而非远程收集 Tomcat 统计信息

java - 生成用于管理 XML 文件的 MBean 的最佳方法