当我导出我的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参数设置这些属性有效,而不是像我上面描述的那样以编程方式设置相同的属性。
这是对我有用的。我假设您已经知道如何正确使用下面示例中的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();