`
QING____
  • 浏览: 2232119 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Jolokia与Spring JMX监控

阅读更多

    Jolokia作为目前最主流的JMX监控组件,spring社区(springboot、MVC、cloud)以及目前主流的中间件服务均采用它作为JMX监控,简单来说,jolokia可以帮助我们解决:

    1)JMX可以实现VM内部运行时数据状态的对外export,我们通过将运行态数据封装成MBean,通过JMX Server统一管理,并允许外部程序通过RMI方式获取数据。总之,JMX允许运行态数据通过RMI协议被外部程序获取。这对我们监控、操作VM内部数据提供窗口。

 

    2)JMX扩展性、可实施能力非常强大,但是其问题就是如果获取MBean数据,需要使用JAVA栈的RMI协议,这对外部程序比如监控组件(非JAVA栈)支持不够良好。

 

    3)jolokia完全兼容并支撑JMX组件,它可以作为agent嵌入到任何JAVA程序中,特别是WEB应用,它将复杂而且难以理解的MBean Filter查询语句,转换成更易于实施和操作的HTTP 请求范式,不仅屏蔽了RMI的开发困难问题,还实现了对外部监控组件的透明度,而且更易于测试和使用。

    4)直观来说,jolokia就是用于解决JMX数据获取时,所遇到的RMI协议复杂性、Mbean查询的不便捷、数据库序列化、MBeanServer的托管等问题;我们只需要使用HTTP请求,直接访问与WEB服务相同的port即可获取JMX数据。

 

    本文不对jolokia做太多的技术性解释,主要描述jolokia在Spring项目中如何使用,以监控tomcat-jdbc连接池为例。

    1)SpringMVC项目

    2)Springboot项目

    3)通过使用telegraf采集组件中jolokia插件,获取jdbc参数,并将数据流转存在kafak(ES中)。(报表部分,可以使用grafana支持)

    4)特别提醒:实现JMX监控的代码方式比较多,本文只描述一种可以达成设计目标的方式,其他方式大家继续探讨即可。

 

一、SpringMVC项目

    1、pom.xml中增加jolokia依赖。

    2、在web.xml中声明jolokia servlet启动和适配。

    3、在resources目录下增加jolokia-access.xml安全访问

    4、在spring xml文件中增加相关MBean export显示操作。(稍后专门讲述有关spring环境下,JMX以注释方式动态绑定)

 

<dependency>
    <groupId>org.jolokia</groupId>
    <artifactId>jolokia-core</artifactId>
    <version>1.3.7</version>
</dependency>

    我们需要在pom.xml中增加jolokia的依赖,建议使用最新版本。

 

    

<servlet>
    <servlet-name>jolokia-agent</servlet-name>
    <servlet-class>org.jolokia.http.AgentServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
  
<servlet-mapping>
    <servlet-name>jolokia-agent</servlet-name>
    <url-pattern>/jolokia/*</url-pattern>
</servlet-mapping>

    我们需要注意,jolokia作为嵌入式agent,将会与我们的web容器一起启动,jolokia agent与web服务共享一个HTTP端口,由此servlet负责承担请求解析。此后可以通过“/jolokia”来访问内部的JMX数据。

 

 

<?xml version="1.0" encoding="UTF-8"?>
<restrict>
    <remote>
        <host>127.0.0.1</host>
        <host>0:0:0:0:0:0:0:1</host>
    </remote>
</restrict>

    jolokia以servlet服务提供给外部程序,那么意味着我们可以通过URL获取数据,在很多时候我们不希望这些数据被外部非法用户获取、只对内部监控组件开发,比如不希望用户通过“域名 + /jolokia”来获取数据等。此jolokia-access.xml表示,只允许"127.0.0.1"即本地的监控组件可以获取数据,对于跨机器、代理程序均无法获取。这也要求我们的telegraf组件是部署在WEB应用的宿主机器上。

 

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
    <property name="url" value="<URL>"/>
    <property name="username" value="<用户名>"/>
    <property name="password" value="<密码>"/>
    <property name="name" value="<本数据源的名称,通常为本bean的id>"></property>
	...
    <property name="jmxEnabled" value="true" />
    <property name="jdbcInterceptors"
value="ConnectionState;StatementCache" />
</bean>
  
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="beans">
        <map>
            <entry
                key="org.apache.tomcat.jdbc.pool.jmx:name=dataSourceMBean,type=ConnectionPool"
                value="#{dataSource.getPool().getJmxPool()}"/>
        </map>
        <!-- 需要注意:jmx:name=dataSourceMBean,
        如果有多个dataSources时建议此值与你的dataSource对应的数据库保持一致,便于监控和分析 
        -->
        <!-- 如果有多个数据源,需要按照上述模式,依次添加 -->
    </property>
</bean>

    考虑SpringMVC无法自动转配MBean,或者说tomcat-jdbc的jmx信息并非Spring支持的JMX注释类型,所以我们有必要人工指定jmxExporter。

    我们可以在jmxExporter中注册我们需要的MBean,当然对于基于@ManagedResource注释的,可以自动适配,这部分我们稍后解释。

 

    此后,我们将可以通过jconsole查看jmx注册列表和相关数据值。也可以通过如下http接口查看jolokia的是否正常:

curl -X GET --header 'Accept: application/json' 'http://127.0.0.1:8080/jolokia/read/org.apache.tomcat.jdbc.pool.jmx:name=dataSourceMBean,type=ConnectionPool'
##dataSourceMBean需要与上文中jmx:name值保持一致

 

二、SpringBoot项目

    Springboot项目,对endpoint管理更加智能化和全面,jmx的支持很封装也更加完善,所以实现jmx监控更加便捷。(建议关注acturator组件)

    1、pom.xml中增加acturator组件的引入,包括jolokia组件。

    2、利用springboot自动装配,我们开启“management”、“endpoint”功能即可。

    3、我们不再需要web.xml以及jolokia-access.xml,因为这些都是默认支持的。(自动装配)

 

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
   
<dependency>
   <groupId>org.jolokia</groupId>
   <artifactId>jolokia-core</artifactId>
</dependency>

 

#jolokia
management:
    security:
        enabled: false
    address: 127.0.0.1
endpoints:
    jolokia:
        enabled: true
  
##datasource
spring:
  datasource:
      url: <URL>
      username: <用户名>
      password: <密码>
      type: org.apache.tomcat.jdbc.pool.DataSource
      tomcat:
            name: dataSource
            jmx-enabled: true
            jdbc-interceptors: ConnectionState;StatementCache

    我们在application.yml文件中增加相应的配置,特别注意management和endpoint部分。

 

    如果我们希望将自定的MBean注册到server中,可以实现@ManagedResource或者,再注入MBeanServer注册也可以。比如自定义的MBean

//以dataSource为例,其他类型的bean可以参考
@Bean(name = "dataSource")
public DataSource dataSource(MBeanServer mBeanServer) {
	...
    try {
        ConnectionPool pool = ((DataSourceProxy) dataSource).createPool().getJmxPool();
        mBeanServer.registerMBean(pool, new ObjectName("org.apache.tomcat.jdbc.pool.jmx:type=ConnectionPool,name=" + dataSourceName));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return dataSource;
}

 

三、telegraf配置样例(以tomcat-jdbc监控为例)

 

[global_tags]
    project = "demo"
[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = true
  logfile = ""
  hostname = ""
  omit_hostname = false
 [[outputs.kafka]]
   brokers = ["10.0.1.2:9092","10.0.1.3:9092","10.0.1.4:9092"]
   topic = "db_pool"
   data_format = "json"
 [[inputs.jolokia]]
   context = "/jolokia/"
   [[inputs.jolokia.servers]]
     name = "dataSource"
     host = "127.0.0.1"
     port = "8080"
   [[inputs.jolokia.metrics]]
     name = "pool_metrics"
     mbean  = "org.apache.tomcat.jdbc.pool.jmx:name=dataSourceMBean,type=ConnectionPool"
     attribute = ""

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics