【问题标题】:Facing issues while setting JVM properties for JMX remote management为 JMX 远程管理设置 JVM 属性时面临的问题
【发布时间】:2014-01-16 09:04:55
【问题描述】:

当我导出我的 JMX 代理以进行远程管理,并将以下参数设置为 VM 参数时

-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false

它工作正常,因为我的 JMX 客户端能够轻松地在端口 9999 与 MBean 建立连接。

现在,我想通过我的配置文件在运行时设置这些属性。 我尝试通过System.setProperty("com.sun.management.jmxremote.port","9999"); 和其他类似的属性进行设置,但无济于事。 JMX 代理不会以这种方式暴露给远程管理。

我什至尝试在端口 9999 上创建一个注册表,但似乎还不够。

private void init() {
    try {
        LocateRegistry.createRegistry(9999);
        System.setProperty("com.sun.management.jmxremote", "true");
        System.setProperty("com.sun.management.jmxremote.authenticate", "false");
        System.setProperty("com.sun.management.jmxremote.port", "9999");
        System.setProperty("com.sun.management.jmxremote.ssl", "false");
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

我只是不明白为什么通过 VM 参数设置这些属性有效,而不是像我上面描述的那样以编程方式设置相同的属性。

【问题讨论】:

    标签: java jmx jvm-arguments


    【解决方案1】:

    这对我有用。我假设您已经知道如何正确使用以下示例中使用的 SimpleMXBean。

    参考Oracle JMX Tutorial。 (请参阅使用 JMX Remote API 模拟开箱即用的管理部分。)

    package sample;
    
    import java.io.IOException;
    import java.lang.management.ManagementFactory;
    import java.rmi.registry.LocateRegistry;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    
    public class MBServerTest {
        public static void loadJMXAgent(int port, MBeanServer mbs) throws IOException  {
            LocateRegistry.createRegistry(port);
            System.out.println("Initialize the environment map");
            Map<String,Object> env = new HashMap<String,Object>();
            env.put("com.sun.management.jmxremote.authenticate", "false");
            env.put("com.sun.management.jmxremote.ssl", "false");
            System.out.println("Create an RMI connector server");
            JMXServiceURL url =
                new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi");
            JMXConnectorServer cs =
                JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
    
            // Start the RMI connector server.
            //
            System.out.println("Start the RMI connector server");
            cs.start();
    
        }
    
        public static void main(String[] args) throws Exception {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            loadJMXAgent(1199,mbs);
    
            SimpleStandard cache = new SimpleStandard();
    
            ObjectName name = new ObjectName(
                    "org.javalobby.tnt.jmx:type=ApplicationCacheMBean");
            mbs.registerMBean(cache, name);
            imitateActivity(cache);
        }
    
        private static void imitateActivity(SimpleStandard cache) {
            while (true) {
                try {
                    cache.cacheObject("hello");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            }
        }
    }
    

    【讨论】:

    • 也可以使用端口0调用LocateRegistry.createRegistry(),它要求内核分配一个临时端口。挖掘该方法调用的结果以提取分配的端口。如果您尝试自动启动运行时进程中缺少的 JMX,这将非常有用。
    【解决方案2】:

    从您的应用程序设置系统属性有点太晚了。 JMX 代理已加载并初始化。

    您可以使用JMX configuration file 将属性存储在一个外部文件中。虽然它不允许您从一个共享配置文件中读取属性,但它至少可以让您将设置外部化到不同的用户属性文件中。

    【讨论】:

      【解决方案3】:

      仅提供该属性可能不会触发在您提供的端口上创建 RMI 连接器。如果您想在运行时启用远程监控,那么我认为您还必须自己在 MBean 服务器上创建连接器。

      查看Oracle JMX tutorial 的“模拟开箱即用管理”一章。特别是示例代码的最后一位,它使用端口 3000 用于 RMI 服务器。这是您要放置所选端口的位置:

      LocateRegistry.createRegistry(3000); 
      Map<String,Object> env = new HashMap<String,Object>();
      env.put("com.sun.management.jmxremote.authenticate", "false");
      env.put("com.sun.management.jmxremote.ssl", "false");
      // Create an RMI connector server.
      //
      // specified in the JMXServiceURL the RMIServer stub will be
      // registered in the RMI registry running in the local host on
      // port 3000 with the name "jmxrmi". This is the same name the
      // out-of-the-box management agent uses to register the RMIServer
      // stub too.
      //
      System.out.println("Create an RMI connector server");
      JMXServiceURL url =
          new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi");
      JMXConnectorServer cs =
          JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
      
      // Start the RMI connector server.
      //
      System.out.println("Start the RMI connector server");
      cs.start();
      

      【讨论】:

      • 这也无济于事。我之前有过的东西但无济于事。我什至发布了上面我尝试过的代码。如果你能发布工作的sn那就太好了-p 以防你已经完成了
      • 我知道评论有点晚了。但是你的代码中有这一行吗? LocateRegistry.createRegistry(3000);
      【解决方案4】:

      尝试在static 块中设置属性。

      static {
          System.setProperty("com.sun.management.jmxremote.port", "9999");
          System.setProperty("com.sun.management.jmxremote.authenticate", "false");
          System.setProperty("com.sun.management.jmxremote.ssl", "false");
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-03
        • 1970-01-01
        • 2011-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多