ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-04 12:12:45  阅读:300  来源: 互联网

标签:java jmx rmi


我有一个程序,它需要动态(即在运行时)打开一个可用的套接字并在其上启动一个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,jmx,rmi
来源: https://codeday.me/bug/20191004/1852878.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有