Jolokia with Spring JMX monitoring

    Jolokia is currently the most mainstream JMX monitoring component. The spring community (springboot, MVC, cloud) and the current mainstream middleware services all use it as JMX monitoring. In short, jolokia can help us solve:

    1) JMX can realize the external export of the runtime data state inside the VM. We encapsulate the runtime data into MBeans, manage them uniformly through the JMX Server, and allow external programs to obtain data through RMI. In summary, JMX allows runtime data to be retrieved by external programs via the RMI protocol. This provides a window for us to monitor and manipulate the internal data of the VM.

 

    2) JMX has strong scalability and implementability, but the problem is that if you want to obtain MBean data, you need to use the RMI protocol of the JAVA stack, which is not good enough for external programs such as monitoring components (non-JAVA stack).

 

    3) Jolokia is fully compatible with and supports JMX components. It can be embedded in any JAVA program as an agent, especially WEB applications. It converts complex and incomprehensible MBean Filter query statements into HTTP request paradigms that are easier to implement and operate. It not only shields the development difficulties of RMI, but also realizes the transparency of external monitoring components, and it is easier to test and use.

    4) Intuitively, jolokia is used to solve the problems of RMI protocol complexity, inconvenience of MBean query, database serialization, MBeanServer hosting and other problems encountered when acquiring JMX data; we only need to use HTTP requests to directly access JMX data can be obtained from the same port as the WEB service.

 

    This article does not do too much technical explanation of jolokia, mainly describes how to use jolokia in Spring projects, taking monitoring tomcat-jdbc connection pool as an example.

    1) SpringMVC project

    2) Springboot project

    3) By using the jolokia plugin in the telegraf acquisition component, the jdbc parameters are obtained, and the data flow is stored in kafak (in ES). (Report part, you can use grafana support)

    4) Special reminder: There are many code ways to implement JMX monitoring. This article only describes one way to achieve the design goal, and you can continue to discuss other ways.

 

1. SpringMVC project

    1. Add jolokia dependency to pom.xml.

    2. Declare jolokia servlet startup and adaptation in web.xml.

    3. Add jolokia-access.xml security access in the resources directory

    4. Add related MBean export display operations in the spring xml file. (We will talk about the dynamic binding of JMX in the form of annotations in the spring environment later)

 

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

    We need to add jolokia dependencies in pom.xml, it is recommended to use the latest version.

 

    

<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>

    We need to note that jolokia, as an embedded agent, will be started with our web container. The jolokia agent shares an HTTP port with the web service, and the servlet is responsible for request parsing. After that, the internal JMX data can be accessed through "/jolokia".

 

 

<?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 provides servlet services to external programs, which means that we can obtain data through URLs. In many cases, we do not want these data to be obtained by external illegal users, and only develop internal monitoring components. For example, we do not want users to pass "domain name + /jolokia" ” to get data, etc. This jolokia-access.xml indicates that only "127.0.0.1" is allowed, that is, the local monitoring component can obtain data, and it cannot be obtained for cross-machine and agent programs. This also requires our telegraf components to be deployed on the host machine of the WEB application.

 

<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="<name of this data source, usually the id of this bean>"></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>
        <!-- Note: jmx:name=dataSourceMBean,
        If there are multiple dataSources, it is recommended that this value be consistent with the database corresponding to your dataSource, which is convenient for monitoring and analysis
        -->
        <!-- If there are multiple data sources, you need to follow the above pattern and add -->
    </property>
</bean>

    Considering that SpringMVC cannot automatically transfer MBeans, or that the jmx information of tomcat-jdbc is not the JMX annotation type supported by Spring, it is necessary to manually specify jmxExporter.

    We can register the MBeans we need in jmxExporter. Of course, those based on @ManagedResource annotations can be automatically adapted. We will explain this part later.

 

    After this, we will be able to view the jmx registration list and related data values ​​through jconsole. You can also check whether jolokia is normal through the following http interface:

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 needs to be consistent with the jmx:name value above

 

Second, the SpringBoot project

    The Springboot project is more intelligent and comprehensive for endpoint management, and the support of jmx is very encapsulated and more complete, so it is more convenient to implement jmx monitoring. (It is recommended to pay attention to the actuator component)

    1. Add the introduction of actuator components in pom.xml, including jolokia components.

    2. Using springboot automatic assembly, we can turn on the "management" and "endpoint" functions.

    3. We no longer need web.xml and jolokia-access.xml as these are supported by default. (automatic assembly)

 

<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: <username>
      password: <password>
      type: org.apache.tomcat.jdbc.pool.DataSource
      tomcat:
            name: dataSource
            jmx-enabled: true
            jdbc-interceptors: ConnectionState;StatementCache

    We add the corresponding configuration in the application.yml file, paying special attention to the management and endpoint sections.

 

    If we want to register a custom MBean in the server, we can implement @ManagedResource or inject the MBeanServer registration. For example, a custom MBean :

//Take dataSource as an example, other types of beans can refer to
@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;
}

 

3. Telegraf configuration example (take tomcat-jdbc monitoring as an example)

 

[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 = ""

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326155239&siteId=291194637
JMX