【问题标题】:Accessing a remote MBean server访问远程 MBean 服务器
【发布时间】:2009-08-13 05:30:19
【问题描述】:

我正在使用 JBoss 运行客户端/服务器应用程序。

如何连接到服务器 JVM 的 MBeanServer?我想使用 MemoryMX MBean 来跟踪内存消耗。

我可以使用 JNDI 查找连接到 JBoss MBeanServer,但是 java.lang.MemoryMX MBean 没有向 JBoss MBeanServer 注册。

编辑:要求是从客户端以编程方式访问内存使用情况。

【问题讨论】:

    标签: java jboss jmx mbeans


    【解决方案1】:

    我写了一个这样的类:

    import javax.management.remote.JMXServiceURL;
    import javax.management.MBeanAttributeInfo;
    import javax.management.MBeanInfo;
    import javax.management.MBeanServerConnection;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    
    public class JVMRuntimeClient 
    {
        static void main(String[] args) throws Exception 
        {
            if (args == null)
        {
            System.out.println("Usage: java JVMRuntimeClient HOST PORT");
        }
        if(args.length < 2)
        {
            System.out.println("Usage: java JVMRuntimeClient HOST PORT");
        }
    
        try
        {
            JMXServiceURL target = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+args[0]+":"+args[1]+"/jmxrmi");
            JMXConnector connector = JMXConnectorFactory.connect(target);
            MBeanServerConnection remote = connector.getMBeanServerConnection();
    
            /**
            * this is the part where you MUST know which MBean to get
            * com.digitalscripter.search.statistics:name=requestStatistics,type=RequestStatistics
            * YOURS WILL VARY!
            */
            ObjectName bean = new ObjectName("com.digitalscripter.search.statistics:name=requestStatistics,type=RequestStatistics");
    
            MBeanInfo info = remote.getMBeanInfo(bean);
            MBeanAttributeInfo[] attributes = info.getAttributes();
            for (MBeanAttributeInfo attr : attributes)
            {
                System.out.println(attr.getDescription() + " " + remote.getAttribute(bean,attr.getName()));
            }
            connector.close();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
            System.exit(0);
        }
       }
    }
    

    【讨论】:

    • 让 JMX 服务 URL 解决了 我的 问题 - 谢谢!
    【解决方案2】:

    与 JBoss 服务器的 MBeanServer 不同,JVM 的 MBean 服务器默认不允许远程监控。您需要设置各种系统属性以允许这样做:

    http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html

    【讨论】:

      【解决方案3】:

      IBM 文章中的代码示例:link

          MBeanServerConnection serverConn;
      
      try {
         //connect to a remote VM using JMX RMI
         JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://<addr>");
      
         JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
      
         serverConn = jmxConnector.getMBeanServerConnection();
      
         ObjectName objName = new 
         ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
      
         // Get standard attribute "VmVendor"
         String vendor = 
         (String) serverConn.getAttribute(objName, "VmVendor");
      
      } catch (...) { }
      

      【讨论】:

        【解决方案4】:

        您是否尝试过启动JConsole(是$JAVA_HOME/bin)来连接服务器?您应该能够从那里查看内存统计信息

        【讨论】:

        • 是的,这行得通。但我想从我的客户端应用程序进行编程访问。我的客户端可以连接到JBoss MBean服务器,但是我不知道如何连接到平台MBean服务器。
        • 道歉 - 从您的问题中不清楚程序访问是一项要求
        【解决方案5】:

        以下代码列出了给定(启用 jmx)java 应用程序的所有 mbean,以及按域分组的属性和操作。只需使用固定的 jmx 端口启动您想要监控的 java 应用程序,例如通过使用这些 vm 参数:

        -Dcom.sun.management.jmxremote
        -Dcom.sun.management.jmxremote.port=9000
        -Dcom.sun.management.jmxremote.local.only=false
        -Dcom.sun.management.jmxremote.ssl=false
        -Dcom.sun.management.jmxremote.authenticate=false

        然后运行这个 main:

        import javax.management.*;
        import javax.management.remote.JMXConnector;
        import javax.management.remote.JMXConnectorFactory;
        import javax.management.remote.JMXServiceURL;
        import java.io.IOException;
        
        public class JmxListAll {
        
            public static void main(String[] args) throws IOException, MalformedObjectNameException, IntrospectionException, InstanceNotFoundException, ReflectionException {
        
                /*
                 1. JMXServiceURL.
                */
                String jmxHost = "localhost:9000"; // exactly like  jconsole localhost:9026
                String url = "service:jmx:rmi:///jndi/rmi://" + jmxHost + "/jmxrmi";
                JMXServiceURL serviceURL = new JMXServiceURL(url);
        
                /*
                 2. JMXConnector and the actual serverConnection
                 */
                JMXConnector connector = JMXConnectorFactory.connect(serviceURL);
                MBeanServerConnection serverConnection = connector.getMBeanServerConnection();
        
                /*
                 3. Walk through the domains and their objects
                 */
                System.out.println("\n     Now we have a look at " + serverConnection.getMBeanCount() + " mbeans!");
                int objectCount = 0;
                for (String domain : serverConnection.getDomains()) {
                    System.out.println("\n***********************************************************************************");
                    System.out.println("DOMAIN: " + domain);
        
                    // query all the beans for this domain using a wildcard filter
                    for (ObjectName objectName : serverConnection.queryNames(new ObjectName(domain + ":*"), null)) {
                        System.out.println("    objectName " + ++objectCount + ": " + objectName);
                        MBeanInfo info = serverConnection.getMBeanInfo(objectName);
                        for (MBeanAttributeInfo attr : info.getAttributes()) {
                            System.out.print("        attr: " + attr.getDescription());
                            try {
                                String val = serverConnection.getAttribute(objectName, attr.getName()).toString();
                                System.out.println(" -> " + abbreviate(val));
                            } catch (Exception e) {
                                System.out.println(" FAILED: " + e);
                            }
                        }
        
                        for (MBeanOperationInfo op : info.getOperations()) {
                            System.out.println("        op: " + op.getName());
                        }
                    }
                }
            }
        
            static String abbreviate(String text) {
                if (text != null && text.length() > 42) {
                    return text.substring(0, 42) + "...";
                } else {
                    return text;
                }
            }
        }
        

        如您所见,在 java.lang 域中有几个与内存相关的 mbean。选择你需要的那个。

        【讨论】:

          猜你喜欢
          • 2013-11-12
          • 2017-04-21
          • 2017-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多