提问者:小点点

为JMX远程管理设置JVM属性时遇到问题


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

-Dcom.sun.management. jmxRemote=true-Dcom.sun.management.jmxRemote.验证=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参数设置这些属性有效,而不是像我上面描述的那样以编程方式设置相同的属性。


共3个答案

匿名用户

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

参考Oracle JMX教程。(请参阅使用JMX远程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) {
            }
        }
    }
}

匿名用户

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

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

匿名用户

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

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

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();