zoukankan      html  css  js  c++  java
  • 如何取得jvm实例的cpu占用(转)

    本文会贴很多代码,代码遵循Google的java代码格式。

    获取数据篇

    1、jmx连接的创建是一个比较重的操作,我们使用apache的common pool2创建连接工厂。

    public class JmxConnectionFactory implements KeyedPooledObjectFactory<JmxServer, JMXConnector> {
    
      @Override
      public PooledObject<JMXConnector> makeObject(JmxServer server) throws Exception {
        JMXServiceURL
            serviceURL =
            new JMXServiceURL(String.format(
                "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", server.getHost(), server.getPort()));
        Map<String, Object> environment = Maps.newHashMap();
        String username = server.getUsername();
        String password = server.getPassword();
        if ((username != null) && (password != null)) {
          String[] credentials = new String[2];
          credentials[0] = username;
          credentials[1] = password;
          environment.put(JMXConnector.CREDENTIALS, credentials);
        }
        environment.put("sun.rmi.transport.proxy.connectTimeout", 1000);
        environment.put("sun.rmi.transport.tcp.responseTimeout", 3000);
        JMXConnector connect = JMXConnectorFactory.connect(serviceURL, environment);
        return new DefaultPooledObject<JMXConnector>(connect);
    
    
      }
    
      @Override
      public void destroyObject(JmxServer key, PooledObject<JMXConnector> object) throws Exception {
        object.getObject().close();
      }
    
      @Override
      public boolean validateObject(JmxServer key, PooledObject<JMXConnector> object) {
        JMXConnector connector = object.getObject();
        try {
          connector.getConnectionId();
          return true;
        } catch (IOException exception) {
          // ignore
        }
        return false;
      }
    
      @Override
      public void activateObject(JmxServer key, PooledObject<JMXConnector> p) throws Exception {
      }
    
      @Override
      public void passivateObject(JmxServer key, PooledObject<JMXConnector> p) throws Exception {
      }
    }
     

    2、从连接池中获取JMX连接

    private static GenericKeyedObjectPool<JmxServer, JMXConnector> POOL;
      private static AtomicInteger actives = new AtomicInteger(0);
      //....
    try {
          JMXConnector connector = POOL.borrowObject(server);
          try {
            MBeanServerConnection mbsc = connector.getMBeanServerConnection();
            // 在这个地方使用连接获取JVM的监控数据
            // ......
          } finally {
            POOL.returnObject(server, connector);
          }
     

    3、计算cpu占用的逻辑是: 获取:ProcessCpuTime,Uptime,AvailableProcessors,然后结合上一次获取到的数据得出,算式为:

    Math.min(99F, (ProcessCpuTime-PreProcessCpuTime) / ((Uptime-PreUptime) * 10000F * AvailableProcessors));
    
    方式一:通过获取相应的Bean,然后通过Bean去获取数据
    
    private long prevUpTime, prevProcessCpuTime;
    // ......
          RuntimeMXBean runtimeMBean =
              newPlatformMXBeanProxy(mbsc, RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
          OperatingSystemMXBean
              operatingSystemMBean =
              newPlatformMXBeanProxy(mbsc, OPERATING_SYSTEM_MXBEAN_NAME,
                                     com.sun.management.OperatingSystemMXBean.class);
          int nCPUs = operatingSystemMBean.getAvailableProcessors();
          if (runtimeMBean != null && operatingSystemMBean != null) {
            long uptime = runtimeMBean.getUptime();
            long processCpuTime = operatingSystemMBean.getProcessCpuTime();
            if (prevUpTime != 0 && prevProcessCpuTime != 0) {
              long elapsedCpu = processCpuTime - prevProcessCpuTime;
              long elaspedTime = uptime - prevUpTime;
              float cpuUsage = Math.min(99F, elapsedCpu / (elaspedTime * 10000F * nCPUs));
              prevUpTime = uptime;
              prevProcessCpuTime = processCpuTime;
              //
              JsonObject value = new JsonObject();
              String key = "CpuUsage";
              LOGGER.debug("received value '{}%' for item '{}'", cpuUsage, key);
              value.addProperty(MonitorConst.JSON_TAG_VALUE, cpuUsage);
              value.addProperty(MonitorConst.JSON_TAG_NAME, key);
              return value;
            } else {
              prevUpTime = uptime;
              prevProcessCpuTime = processCpuTime;
            }
          }
    // ......

    方式二、通过key来直接获取,代码通用些,比较长,代码参考zabbix gateway实现

    // 通用获取方法
    
    protected String getStringValue(MBeanServerConnection mbsc, String key) throws Exception {
        MonitorItem item = new MonitorItem(key);
    
        if (item.getKeyId().equals("jmx")) {
      if (2 != item.getArgumentCount()) {
        throw new MonitorException(
        "required key format: jmx[<object name>,<attribute name>]");
      }
    
      ObjectName objectName = new ObjectName(item.getArgument(1));
      String attributeName = item.getArgument(2);
      String realAttributeName;
      String fieldNames = "";
      int sep;
    
      //
      // Attribute name and composite data field names are separated by dots. On the other hand the
      // name may contain a dot too. In this case user needs to escape it with a backslash. Also the
      // backslash symbols in the name must be escaped. So a real separator is unescaped dot and
      // separatorIndex() is used to locate it.
      //
    
      sep = HelperFunctionChest.separatorIndex(attributeName);
    
      if (-1 != sep) {
        LOGGER.trace("'{}' contains composite data", attributeName);
    
        realAttributeName = attributeName.substring(0, sep);
        fieldNames = attributeName.substring(sep + 1);
      } else {
        realAttributeName = attributeName;
      }
    
      // unescape possible dots or backslashes that were escaped by user
      realAttributeName = HelperFunctionChest.unescapeUserInput(realAttributeName);
    
      LOGGER.trace("attributeName:'{}'", realAttributeName);
      LOGGER.trace("fieldNames:'{}'", fieldNames);
    
      return getPrimitiveAttributeValue(mbsc.getAttribute(objectName, realAttributeName),
                    fieldNames);
        } else if (item.getKeyId().equals("jmx.discovery")) {
      if (0 != item.getArgumentCount()) {
        throw new MonitorException("required key format: jmx.discovery");
      }
    
      JsonArray counters = new JsonArray();
    
      for (ObjectName name : mbsc.queryNames(null, null)) {
        LOGGER.trace("discovered object '{}'", name);
    
        for (MBeanAttributeInfo attrInfo : mbsc.getMBeanInfo(name).getAttributes()) {
          LOGGER.trace("discovered attribute '{}'", attrInfo.getName());
    
          if (!attrInfo.isReadable()) {
        LOGGER.trace("attribute not readable, skipping");
        continue;
          }
    
          try {
        LOGGER.trace("looking for attributes of primitive types");
        String
            descr =
            (attrInfo.getName().equals(attrInfo.getDescription()) ? null
                              : attrInfo
             .getDescription());
        findPrimitiveAttributes(counters, name, descr, attrInfo.getName(),
                mbsc.getAttribute(name, attrInfo.getName()));
          } catch (Exception e) {
        Object[] logInfo = {name, attrInfo.getName(), e};
        LOGGER.trace("processing '{},{}' failed", logInfo);
          }
        }
      }
    
      JsonObject mapping = new JsonObject();
      mapping.add(MonitorConst.JSON_TAG_DATA, counters);
      return mapping.toString();
        } else {
      throw new MonitorException("key ID '%s' is not supported", item.getKeyId());
        }
      }
    
      private String getPrimitiveAttributeValue(Object dataObject, String fieldNames) throws
                                  MonitorException {
        LOGGER
        .trace("drilling down with data object '{}' and field names '{}'", dataObject,
           fieldNames);
    
        if (null == dataObject) {
      throw new MonitorException("data object is null");
        }
    
        if (fieldNames.equals("")) {
      if (isPrimitiveAttributeType(dataObject.getClass())) {
        return dataObject.toString();
      } else {
        throw new MonitorException(
        "data object type is not primitive: %s" + dataObject.getClass());
      }
        }
    
        if (dataObject instanceof CompositeData) {
      LOGGER.trace("'{}' contains composite data", dataObject);
    
      CompositeData comp = (CompositeData) dataObject;
    
      String dataObjectName;
      String newFieldNames = "";
    
      int sep = HelperFunctionChest.separatorIndex(fieldNames);
    
      if (-1 != sep) {
        dataObjectName = fieldNames.substring(0, sep);
        newFieldNames = fieldNames.substring(sep + 1);
      } else {
        dataObjectName = fieldNames;
      }
    
      // unescape possible dots or backslashes that were escaped by user
      dataObjectName = HelperFunctionChest.unescapeUserInput(dataObjectName);
    
      return getPrimitiveAttributeValue(comp.get(dataObjectName), newFieldNames);
        } else {
      throw new MonitorException("unsupported data object type along the path: %s",
                 dataObject.getClass());
        }
      }
    
      private void findPrimitiveAttributes(JsonArray counters, ObjectName name, String descr,
                   String attrPath, Object attribute) {
        LOGGER.trace("drilling down with attribute path '{}'", attrPath);
    
        if (isPrimitiveAttributeType(attribute.getClass())) {
      LOGGER.trace("found attribute of a primitive type: {}", attribute.getClass());
    
      JsonObject counter = new JsonObject();
    
      counter.addProperty("{#JMXDESC}", null == descr ? name + "," + attrPath : descr);
      counter.addProperty("{#JMXOBJ}", name.toString());
      counter.addProperty("{#JMXATTR}", attrPath);
      counter.addProperty("{#JMXTYPE}", attribute.getClass().getName());
      counter.addProperty("{#JMXVALUE}", attribute.toString());
    
      counters.add(counter);
        } else if (attribute instanceof CompositeData) {
      LOGGER.trace("found attribute of a composite type: {}", attribute.getClass());
    
      CompositeData comp = (CompositeData) attribute;
    
      for (String key : comp.getCompositeType().keySet()) {
        findPrimitiveAttributes(counters, name, descr, attrPath + "." + key, comp.get(key));
      }
        } else if (attribute instanceof TabularDataSupport || attribute.getClass().isArray()) {
      LOGGER.trace("found attribute of a known, unsupported type: {}", attribute.getClass());
        } else {
      LOGGER
          .trace("found attribute of an unknown, unsupported type: {}", attribute.getClass());
        }
      }
    
      private boolean isPrimitiveAttributeType(Class<?> clazz) {
        Class<?>[]
        clazzez =
        {Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class,
         Float.class, Double.class, String.class, java.math.BigDecimal.class,
         java.math.BigInteger.class,
         java.util.Date.class, ObjectName.class};
    
        return HelperFunctionChest.arrayContains(clazzez, clazz);
      }
    
    // 使用示例
    获取:ProcessCpuTime,Uptime,AvailableProcessors,然后结合上一次获取到的数据得出,算式为:
    String processCpuTime=getStringValue(mbsc, "jmx["java.lang:type=OperatingSystem",ProcessCpuTime]")
    String uptime=getStringValue(mbsc, "jmx["java.lang:type=Runtime",Uptime]", #1)-last("jmx["java.lang:type=Runtime",Uptime]")
    String availableProcessors=getStringValue(mbsc, "jmx["java.lang:type=OperatingSystem",AvailableProcessors]")

    方式三、zabbix 1、clone一个Template JMX Generic,修改添加相应的item的配置,添加的Template JMX Consumer

    <template>
          <template>Template JMX Consumer</template>
          <name>Template JMX Consumer</name>
          <groups>
            <group>
              <name>Templates</name>
            </group>
          </groups>
          <applications/>
          <items>
            <item>
              <name>AvailableProcessors</name>
              <type>16</type>
              <snmp_community/>
              <multiplier>0</multiplier>
              <snmp_oid/>
              <key>jmx["java.lang:type=OperatingSystem",AvailableProcessors]</key>
              <delay>60</delay>
              <history>7</history>
              <trends>365</trends>
              <status>0</status>
              <value_type>3</value_type>
              <allowed_hosts/>
              <units/>
              <delta>0</delta>
              <snmpv3_contextname/>
              <snmpv3_securityname/>
              <snmpv3_securitylevel>0</snmpv3_securitylevel>
              <snmpv3_authprotocol>0</snmpv3_authprotocol>
              <snmpv3_authpassphrase/>
              <snmpv3_privprotocol>0</snmpv3_privprotocol>
              <snmpv3_privpassphrase/>
              <formula>1</formula>
              <delay_flex/>
              <params/>
              <ipmi_sensor/>
              <data_type>0</data_type>
              <authtype>0</authtype>
              <username/>
              <password/>
              <publickey/>
              <privatekey/>
              <port/>
              <description/>
              <inventory_link>0</inventory_link>
              <applications>
                <application>
                  <name>Operating System</name>
                </application>
              </applications>
              <valuemap/>
            </item>
            <item>
              <name>Cpu Usage</name>
              <type>15</type>
              <snmp_community/>
              <multiplier>0</multiplier>
              <snmp_oid/>
              <key>CpuUsage</key>
              <delay>30</delay>
              <history>7</history>
              <trends>365</trends>
              <status>0</status>
              <value_type>0</value_type>
              <allowed_hosts/>
              <units>%</units>
              <delta>0</delta>
              <snmpv3_contextname/>
              <snmpv3_securityname/>
              <snmpv3_securitylevel>0</snmpv3_securitylevel>
              <snmpv3_authprotocol>0</snmpv3_authprotocol>
              <snmpv3_authpassphrase/>
              <snmpv3_privprotocol>0</snmpv3_privprotocol>
              <snmpv3_privpassphrase/>
              <formula>1</formula>
              <delay_flex/>
              <params>(last("jmx["java.lang:type=OperatingSystem",ProcessCpuTime]", #1)-last("jmx["java.lang:type=OperatingSystem",ProcessCpuTime]", #2))/((last("jmx["java.lang:type=Runtime",Uptime]", #1)-last("jmx["java.lang:type=Runtime",Uptime]", #2))*10000*last("jmx["java.lang:type=OperatingSystem",AvailableProcessors]", 0))</params>
              <ipmi_sensor/>
              <data_type>0</data_type>
              <authtype>0</authtype>
              <username/>
              <password/>
              <publickey/>
              <privatekey/>
              <port/>
              <description/>
              <inventory_link>0</inventory_link>
              <applications>
                <application>
                  <name>Runtime</name>
                </application>
              </applications>
              <valuemap/>
            </item>
            <item>
              <name>ProcessCpuTime</name>
              <type>16</type>
              <snmp_community/>
              <multiplier>0</multiplier>
              <snmp_oid/>
              <key>jmx["java.lang:type=OperatingSystem",ProcessCpuTime]</key>
              <delay>60</delay>
              <history>7</history>
              <trends>365</trends>
              <status>0</status>
              <value_type>3</value_type>
              <allowed_hosts/>
              <units/>
              <delta>0</delta>
              <snmpv3_contextname/>
              <snmpv3_securityname/>
              <snmpv3_securitylevel>0</snmpv3_securitylevel>
              <snmpv3_authprotocol>0</snmpv3_authprotocol>
              <snmpv3_authpassphrase/>
              <snmpv3_privprotocol>0</snmpv3_privprotocol>
              <snmpv3_privpassphrase/>
              <formula>1</formula>
              <delay_flex/>
              <params/>
              <ipmi_sensor/>
              <data_type>0</data_type>
              <authtype>0</authtype>
              <username/>
              <password/>
              <publickey/>
              <privatekey/>
              <port/>
              <description/>
              <inventory_link>0</inventory_link>
              <applications>
                <application>
                  <name>Operating System</name>
                </application>
              </applications>
              <valuemap/>
            </item>
          </items>
          <discovery_rules/>
          <macros/>
          <templates>
            <template>
              <name>Template JMX Generic</name>
            </template>
          </templates>
          <screens/>
        </template>
    // 修改原来的模板
    <item>
              <name>jvm Uptime</name>
              <type>15</type>
              <snmp_community/>
              <multiplier>1</multiplier>
              <snmp_oid/>
              <key>jmxUptime</key>
              <delay>60</delay>
              <history>7</history>
              <trends>365</trends>
              <status>0</status>
              <value_type>3</value_type>
              <allowed_hosts/>
              <units>uptime</units>
              <delta>0</delta>
              <snmpv3_contextname/>
              <snmpv3_securityname/>
              <snmpv3_securitylevel>0</snmpv3_securitylevel>
              <snmpv3_authprotocol>0</snmpv3_authprotocol>
              <snmpv3_authpassphrase/>
              <snmpv3_privprotocol>0</snmpv3_privprotocol>
              <snmpv3_privpassphrase/>
              <formula>0.001</formula>
              <delay_flex/>
              <params>jmx["java.lang:type=Runtime",Uptime]</params>
              <ipmi_sensor/>
              <data_type>0</data_type>
              <authtype>0</authtype>
              <username/>
              <password/>
              <publickey/>
              <privatekey/>
              <port/>
              <description/>
              <inventory_link>0</inventory_link>
              <applications>
                <application>
                  <name>Runtime</name>
                </application>
              </applications>
              <valuemap/>
            </item>
            <item>
              <name>jvm Uptime Microsecond</name>
              <type>16</type>
              <snmp_community/>
              <multiplier>0</multiplier>
              <snmp_oid/>
              <key>jmx["java.lang:type=Runtime",Uptime]</key>
              <delay>60</delay>
              <history>7</history>
              <trends>365</trends>
              <status>0</status>
              <value_type>3</value_type>
              <allowed_hosts/>
              <units>uptime</units>
              <delta>0</delta>
              <snmpv3_contextname/>
              <snmpv3_securityname/>
              <snmpv3_securitylevel>0</snmpv3_securitylevel>
              <snmpv3_authprotocol>0</snmpv3_authprotocol>
              <snmpv3_authpassphrase/>
              <snmpv3_privprotocol>0</snmpv3_privprotocol>
              <snmpv3_privpassphrase/>
              <formula>1</formula>
              <delay_flex/>
              <params/>
              <ipmi_sensor/>
              <data_type>0</data_type>
              <authtype>0</authtype>
              <username/>
              <password/>
              <publickey/>
              <privatekey/>
              <port/>
              <description/>
              <inventory_link>0</inventory_link>
              <applications>
                <application>
                  <name>Runtime</name>
                </application>
              </applications>
              <valuemap/>
            </item>
     
  • 相关阅读:
    我理解的朴素贝叶斯模型
    P2P贷款全攻略,贷前、贷中、贷后工作事项解析
    Jupyter Notebook 快速入门
    R语言|数据特征分析
    R语言︱处理缺失数据&&异常值检验、离群点分析、异常值处理
    mysql explain执行计划详解
    R语言中的回归诊断-- car包
    一行代码搞定 R 语言模型输出!(使用 stargazer 包)
    基于R语言的时间序列指数模型
    基于R语言的ARIMA模型
  • 原文地址:https://www.cnblogs.com/zhengah/p/4941958.html
Copyright © 2011-2022 走看看