• 【JMX】jmx结合jmx_exporter实现promethues监控


    JMX

    JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展。这种机制可以方便的管理、监控正在运行中的Java程序。常用于管理线程,内存,日志Level,服务重启,系统环境等

    基本术语

    • MBean:
      是Managed Bean的简称,可以翻译为“管理构件”。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用自醒和反射来获取Object的值和调用Object的方法,只是MBean更为复杂和高级一些。MBean通过公共方法以及遵从特定的设计模式封装了属性和操作,以便暴露给管理应用程序。例如,一个只读属性在管理构件中只有Get方法,既有Get又有Set方法表示是一个可读写的属性。一共有四种类型的MBean:

      • Standard MBean,
      • Dynamic MBean,
      • Open MBean,
      • Model MBean。
    • MBeanServer:
      MBean生存在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。并且MBeanServer提供了一种注册机制,是的外界可以通过名字来得到相应的MBean实例。

    • JMX Agent:
      Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的- - - MbeanService。当然这些Service也是通过MBean的形式来发布。

    • Protocol Adapters and Connectors:
      MBeanServer依赖于Protocol Adapters和Connectors来和运行该代理的Java虚拟机之外的管理应用程序进行通信。Protocol Adapters通过特定的协议提供了一张注册在MBeanServer的MBean的视图。例如,一个HTML Adapter可以将所有注册过的MBean显示在Web 页面上。不同的协议,提供不同的视图。Connectors还必须提供管理应用一方的接口以使代理和管理应用程序进行通信,即针对不同的协议,Connectors必须提供同样的远程接口来封装通信过程。当远程应用程序使用这个接口时,就可以通过网络透明的和代理进行交互,而忽略协议本身。Adapters和Connectors使MBean服务器与管理应用程序能进行通信。因此,一个代理要被管理,它必须提供至少一个Protocol Adapter或者Connector。面临多种管理应用时,代理可以包含各种不同的Protocol Adapters和Connectors。当前已经实现和将要实现的Protocol Adapters和Connectors包括: RMI Connector, SNMP Adapter, IIOP Adapter, HTML Adapter, HTTP Connector.

    Adapter 和Connector的区别在于:Adapter是使用某种Internet协议来与JMX Agent获得联系,Agent端会有一个对象 (Adapter)来处理有关协议的细节。比如SNMP Adapter和HTTP Adapter。而Connector则是使用类似RPC的方式来访问Agent,在Agent端和客户端都必须有这样一个对象来处理相应的请求与应答。比如RMI Connector。

    Spring JMX

    为了将一个POJO变为MBean,一个做法是定义一个XXXXMBean为名的接口,然后实现它。
    而Spring提供了一种更简单的方法,Annotation注释即可,既可以将POJO变为MBean,还可以为属性,方法及其参数都加上描述,为JConsole进行操作时提供更好的帮助信息。

    • @ManagedResource 在类上使用,把类标记为MBean。
    • @ManagedOperation 在可操作的方法加使用。
    • @ManagedAttribute 在字段上使用。如果属性是可读可写的,就在getter和setter上都注释,只读的话就只在getter上注释。
    package com.example.demo.jmx;
    
    import org.springframework.jmx.export.annotation.ManagedAttribute;
    import org.springframework.jmx.export.annotation.ManagedOperation;
    import org.springframework.jmx.export.annotation.ManagedResource;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.atomic.AtomicLong;
    @Component
    @ManagedResource(objectName="test.jmx:name=ServerManager",
            description="Server manager.")
    public class Hello {
    
        private final AtomicLong alarm = new AtomicLong(0);
    
        @ManagedAttribute
        public Integer getAlarm() {
            return alarm.intValue();
        }
    
        @ManagedOperation
        public void setAlarm() {
            alarm.incrementAndGet();
        }
    }
    
    

    新建一个SpringBoot项目,添加像上面使用注解的类,启动项目后,就可以在JConsole查看MBean的情况了。

    支持JMX远程连接

    如果是用Jolokia将JMX Restful JSON的话,远程连接就不是必须的。如果仍然要远程连接,可以在启动JVM时加上系统参数

    -Dcom.sun.management.jmxremote.authenticate=false
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.port=3099
    

    JConsole

    如果JConsole与应用在同一台机器,直接选择该进程
    远程进程URL可以简单的写host:portlocalhost:2099
    练打字的话写完整版的service:jmx:rmi:///jndi/rmi://localhost:2099/jmxrmi

    自定义MBean(非Spring方式)

    1. 新建接口
    package com.example.demo.jmx;
    
    public interface AlarmMBean {
        Integer getAlarm();
        void setAlarm();
    }
    
    1. 新建实现类
    package com.example.demo.jmx;
    import java.util.concurrent.atomic.AtomicLong;
    
    public class Alarm implements AlarmMBean{
    
        private final AtomicLong alarm = new AtomicLong(0);
    
        @Override
        public Integer getAlarm() {
            return alarm.intValue();
        }
    
        @Override
        public void setAlarm() {
            alarm.incrementAndGet();
        }
    }
    
    
    1. 注册MBean
      Demo程序在main访法中调用即可
        private static void registerMBean(String module,Integer errorCode) {
            try {
                MBeanServer server = ManagementFactory.getPlatformMBeanServer();
                ObjectName name = new ObjectName("jmxBean:name="+module+"-"+errorCode);
                //create mbean and register mbean
                server.registerMBean(new Alarm(), name);
    
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    
    1. 支持JConsole远程连接
        private static void jmxConnect() {
            try {
                MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    
                LocateRegistry.createRegistry(9999);
                //URL路径的结尾可以随意指定,但如果需要用Jconsole来进行连接,则必须使用jmxrmi
                JMXServiceURL url = new JMXServiceURL
                        ("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
                JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
                System.out.println("begin rmi start");
                jcs.start();
                System.out.println("rmi start");
    
            } catch (Exception e) {
                System.out.println(e);
            }
    
        }
    

    这样就可以在JConsole中用localhost:9999连接。

    prometheus jmx_exporter

    通过HTTP公开JMX Bean以供Prometheus使用的过程
    https://github.com/prometheus/jmx_exporter

    配置文件config.yaml

    --- 
    lowercaseOutputLabelNames: true
    lowercaseOutputName: true
    #whitelistObjectNames: ["java.lang:type=OperatingSystem","jmxBean:type=custom",*]
    #blacklistObjectNames: []
    rules:
       #在JConsole中可观察到自定义MBean:jmxBean:name=reactor-100102
      - pattern: 'jmxBean<name=(w+)-(d+)><>(alarm):'
        name: test_$1_$2
        labels:
          "module": "$1"
          "errorCode": "$2"
        type: COUNTER
        attrNameSnakeCase: true
    

    whitelistObjectNames 中配置MBean的白名单,缺省设置默认是全部公开的MBean。
    ()每个小括号的正则结果对应$1,$2...的变量。
    更多的选项设置Github文档中有更详细描述和示例配置。

    模式匹配格式 (pattern)

    与模式匹配的输入格式为

    domain<beanpropertyName1=beanPropertyValue1, beanpropertyName2=beanPropertyValue2, ...><key1, key2, ...>attrName: value
    
    部分 描述
    domain 定义ObjectName时,JMX对象名称中冒号之前的部分。
    beanProperyName/Value Bean属性。这些是JMX对象名称中冒号后面的键/值。
    key 如果遇到复合数据或表格数据,则将属性名称添加到此列表中。
    attrName 属性的名称。对于表格数据,这将是列的名称
    value 属性的值。

    预设格式

    在大多数情况下,缺省格式将以一种可以产生健全度量标准的方式转换bean。它是

    domain_beanPropertyValue1_key1_key2_...keyN_attrName{beanpropertyName2="beanPropertyValue2", ...}: value
    

    javaagent运行

    要作为javaagent运行,请下载jar并运行:
    java -javaagent:./jmx_prometheus_javaagent-0.12.0.jar=8081:config.yaml -jar yourJar.jar
    现在可以在http://localhost:8081 上访问指标
    要将Java代理绑定到特定IP,请将端口号更改为host:port。

    JavaAgent.java

    https://github.com/prometheus/jmx_exporter/blob/master/jmx_prometheus_javaagent/src/main/java/io/prometheus/jmx/JavaAgent.java

    Prometheus和Grafana的配置这里不讲,可以找其它文章进行配置。

    参考链接:
    https://www.cnblogs.com/dongguacai/p/5900507.html
    https://blog.csdn.net/u013256816/article/details/52800742
    https://github.com/springside/springside4/wiki/Jmx
    https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/boot-features-jmx.html
    https://github.com/prometheus/jmx_exporter

  • 相关阅读:
    P1582 倒水 (二进制)
    P2014 选课 (树形动规)
    多项式前置技能——复数
    P3694 邦邦的大合唱站队 (状压DP)
    P1754 球迷购票问题 (卡特兰数,递推)
    [SCOI2003]字符串折叠 (区间DP)
    [SDOI2008]仪仗队 (欧拉函数)
    4-字符串
    3.输出,输入,基本数据类型
    2.栈,堆,寄存器的理解
  • 原文地址:https://www.cnblogs.com/longling2344/p/11687051.html
Copyright © 2020-2023  润新知