这是我的博客文章“JRCMD走得更远”的更新版本。在JRockit R27版中,Mbean有了重大修改,用于公开JRockit特有的可管理功能。一个主要的不同在于,JRockit特有的功能并非默认加载到平台MBean服务器中。要进行加载,必须先创建一个特定的MBean,然后该MBean将加载用于公开该API的剩余部分。MBean也将移动到新域:“bea.jrockit.management”。
要加载的MBean是bea.jrockit.management:JRockitConsole MBean。只需使用MBeanServerConnection就可以完成,如下所示:
MBeanServerConnection#createMBean(
"bea.jrockit.management.JRockitConsole", null);
以下示例是旧的JRCMD走得更远 的修改版本,和JRCMD一样,允许读取/执行性能计数器和ctrl-break处理程序,但是从另一台机器远程读取/执行。
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
/**
* Simple code example on how to execute ctrl-break handlers remotely.
*
* Usage: RemoteJRCMD -host -port -user -pass
* -command []
*
* All arguments are optional. If no command is specified, all performance
* counters and their current values are listed.
*
* @author Marcus Hirt
*/
public class RemoteJRCMD {
private final static String KEY_CREDENTIALS = "jmx.remote.credentials";
private final static String JROCKIT_PERFCOUNTER_MBEAN_NAME = "bea.jrockit.management:type=PerfCounters";
private final static String JROCKIT_CONSOLE_MBEAN_NAME = "bea.jrockit.management:type=JRockitConsole";
private final static String[] SIGNATURE = new String[] { "java.lang.String" };
public static void main(String[] args) throws Exception {
HashMap commandMap = new HashMap();
commandMap.put("-host", "localhost");
commandMap.put("-port", "7091");
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
StringBuilder buf = new StringBuilder();
int j = i + 1;
while (j < args.length && !args[j].startsWith("-")) {
buf.append(" ");
buf.append(args[j++]);
}
commandMap.put(args[i], buf.toString().trim());
i = j - 1;
}
}
executeCommand((String) commandMap.get("-host"), Integer
.parseInt(commandMap.get("-port")), commandMap.get("-user"), commandMap
.get("-password"), commandMap.get("-command"));
}
public static void executeCommand(String host, int port, String user,
String password, String command) throws Exception {
MBeanServerConnection server = null;
JMXConnector jmxc = null;
Map map = null;
if (user != null || password != null) {
map = new HashMap();
final String[] credentials = new String[2];
credentials[0] = user;
credentials[1] = password;
map.put(KEY_CREDENTIALS, credentials);
}
// Use same convention as Sun. localhost:0 means "VM, monitor thyself!"
if (host.equals("localhost") && port == 0) {
server = ManagementFactory.getPlatformMBeanServer();
} else {
jmxc = JMXConnectorFactory.newJMXConnector(
createConnectionURL(host, port), map);
jmxc.connect();
server = jmxc.getMBeanServerConnection();
}
System.out.println("Connected to " + host + ":" + port);
try {
server.getMBeanInfo(new ObjectName(JROCKIT_CONSOLE_MBEAN_NAME));
} catch (InstanceNotFoundException e1) {
server.createMBean("bea.jrockit.management.JRockitConsole", null);
}
if (command == null) {
ObjectName perfCounterObjectName = new ObjectName(
JROCKIT_PERFCOUNTER_MBEAN_NAME);
System.out.println("Listing all counters...");
MBeanAttributeInfo[] attributes = server.getMBeanInfo(
perfCounterObjectName).getAttributes();
System.out.println("Counter\tValue\n=======\t====");
String[] attributeNames = new String[attributes.length];
for (int i = 0; i < attributes.length; i++) {
attributeNames[i] = attributes[i].getName();
}
Iterator valueIter = server.getAttributes(perfCounterObjectName,
attributeNames).iterator();
while (valueIter.hasNext()) {
Attribute attr = (Attribute) valueIter.next();
System.out.println(attr.getName() + "\t=\t" + attr.getValue());
}
} else {
System.out
.println("Invoking the ctrl-break command '" + command + "'...");
ObjectName consoleObjectName = new ObjectName(JROCKIT_CONSOLE_MBEAN_NAME);
Object[] params = new Object[1];
params[0] = command;
System.out.println("The CtrlBreakCommand returned: \n"
+ server.invoke(consoleObjectName, "runCtrlBreakHandlerWithResult",
params, SIGNATURE));
}
if (jmxc != null) {
jmxc.close();
}
}
private static JMXServiceURL createConnectionURL(String host, int port)
throws MalformedURLException {
return new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port
+ "/jmxrmi");
}
}
以下示例将对localhost上的默认端口(7091)列出所有性能计数器及其值:
java RemoteJRCMD
以下示例将对运行在主机bitsy、端口7099的JRockit启动一个60秒的JRA记录,并根据名为nisse.zip的文件编写结果记录:
java RemoteJRCMD -command jrarecordingfilename=nisse time=60 -host bitsy -port 7091
和往常一样,不要忘记对您希望监控的JRockit启用JMX管理代理。可以使用 –Xmanagement选项启用管理代理,如下所示:
-Xmanagement:port=7091,ssl=false,authenticate=false
原文出处:http://dev2dev.bea.com/blog/hirt/archive/2007/03/jrcmd_goes_remo_1.html