我有一个本地运行的嵌入式Jetty应用程序,并且已连接到它的jconsole。当我订阅来自java.lang.Memory的通知时,即使我手动触发垃圾收集,我也看不到任何通知。我是JMX的新手,但我的理解是,默认情况下应该提供像GarbageCollectorMXBean和MemoryMXBean这样的平台mbeans,不需要配置。这是对的吗?
我按如下方式配置JMX,其中server是jetty服务器:
private void configureJmx(CommandLine cmd) {
String jmxRmiHost = cmd.getOptionValue("jmxRmiHost");
String jmxRmiPortString = cmd.getOptionValue("jmxRmiPort");
String jmxPasswordFile = cmd.getOptionValue("jmxPasswordFile");
String jmxAccessFile = cmd.getOptionValue("jmxAccessFile");
if (jmxRmiHost != null || jmxRmiPortString != null || jmxPasswordFile != null || jmxAccessFile != null) {
if (jmxRmiHost == null || jmxRmiPortString == null || jmxPasswordFile == null || jmxAccessFile == null) {
throw new IllegalStateException("If any of -jmxRmiHost, -jmxRmiPort, -jmxPasswordFile or -jmxAccessFile "
+ "are set, then all of them must be");
} else {
int jmxRmiPort = Integer.valueOf(jmxRmiPortString);
MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addEventListener(mbContainer);
server.addBean(mbContainer);
server.addBean(Log.getLog());
String rmiUrl = "/jndi/rmi://" + jmxRmiHost + ":" + jmxRmiPort + "/jmxrmi";
try {
JMXServiceURL jmxServiceUrl = new JMXServiceURL("rmi", jmxRmiHost, jmxRmiPort, rmiUrl);
Map<String, String> jmxEnvironment = new HashMap<String, String>(2);
jmxEnvironment.put("jmx.remote.x.password.file", jmxPasswordFile);
jmxEnvironment.put("jmx.remote.x.access.file", jmxAccessFile);
String name = "org.eclipse.jetty.jmx:name=rmiconnectorserver";
ConnectorServer connectorServer = new ConnectorServer(jmxServiceUrl, jmxEnvironment, name);
connectorServer.start();
} catch (Exception e) {
throw new RuntimeException("Unable to configure JMX: " + e);
}
}
}
}
据推测,在jconsole中,我应该只需在MBeans选项卡中选择mbean,然后点击“订阅”即可。看到它的通知?
感谢您的帮助。
编辑:刚刚尝试在调用java时添加以下args。仍然没有运气。
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
答案 0 :(得分:1)
事实证明我接收的是JMX通知,但我期待的MBean不存在。这是因为当我们从独立更改为嵌入式Jetty时,我们忘记使用相同的参数调用java。我检查了Jetty的配置文件,发现它使用了以下命令行参数。
-XX:+UseConcMarkSweepGC
-XX:ParallelCMSThreads=2
-XX:+CMSClassUnloadingEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=80
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+PrintTenuringDistribution
-XX:+PrintCommandLineFlags
-XX:+DisableExplicitGC
使用上述方法运行应用程序解决了问题。