跳到导航
BEA Dev2Dev Oracle and BEA
首页 资源中心 dev2dev学堂 在线技术论坛 User Group CodeShare
dev2dev 首页 > 资源中心 > 专家Blog > 专家Blog文章
JRCMD走得更远

时间:2006-02-23
作者:Marcus Hirt
浏览次数:
本文关键字:JRockitJRCMDperfcounterJMX
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

  长时间以来,JRockit就一直可以在启动后使用ctrl-break/kill -3信号处理程序以一种非常简洁的方式与JVM交互。只需将一个名为ctrlhandler.act的文件放到当前工作目录下,按下ctrl-break(Windows下),然后文件就会被分析,文件中的命令就会被执行。更多信息请参见我的文章:轻松玩转JROCKIT 5.0——轻松玩转JVM

  我们介绍了一种使用JRCMD命令行工具的更简单的方法,该工具可以用于在本地机器上列出所有的性能计数器,或者在JRockit进程上运行ctrl-break处理程序。
下面的例子是perfcounter例子(请参见我以前的一篇文章)的扩展版本,它也像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.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 <host> -port <host> -user <user>
 * -pass <password> -command <command> [<params>]
 * 
 * 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 = 
      "com.jrockit:type=JRockitPerfCounters";
   private final static String      JROCKIT_CONSOLE_MBEAN_NAME     = 
      "com.jrockit: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(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);

      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、端口7091上的JRockit上启动一个60秒的JRA记录,并将生成的记录写入一个名为nisse.zip的文件中:

  java RemoteJRCMD -command jrarecording filename=nisse time=60 -host bitsy -port 7091

  与往常一样,不要忘了启用希望监控的JRockit的JMX管理代理。

原文出处:http://dev2dev.bea.com/blog/hirt/archive/2005/12/jrcmd_goes_remo.html

dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分