性能监控之Telegraf+InfluxDB+Grafana实现JMX实时监控

举报
zuozewei 发表于 2021/08/24 21:37:44 2021/08/24
【摘要】 性能测试需要监控服务端 JVM 信息,Java 虚拟机 (JVM) 提供操作管理和监测提供了一套完整框架,即 JMX(Java 管理扩展),我们需要做到采集其所暴露出来的性能指标。

背景

性能测试需要监控服务端 JVM 信息,Java 虚拟机 (JVM) 提供操作管理和监测提供了一套完整框架,即 JMX(Java 管理扩展),我们需要做到采集其所暴露出来的性能指标。

什么是JMX?

JMX 技术定义了完整的架构和设计模式集合,以对 Java 应用进行监测和管理。JMX 的基础是托管豆(managed bean,业内更习惯将其称为 MBean),MBean 是通过依赖注入完成实例化的各个类别,代表着 JVM 中的资源。由于 MBean 代表 JVM 中的资源,所以我们可以用其来管理应用的特定方面,或者更为常见的一种做法,用其来收集与这些资源的使用相关的统计数据。JMX 的核心是 MBean 服务器,此类服务器可以作为媒介将 MBean、同一 JVM 内的应用以及外部世界联系在一起。与 MBean 之间的任何交互都是通过此服务器完成的。通常而言,只有 Java 代码能够直接访问 JMX API,但是有一些适配器可将该 API 转换为标准协议,例如 Jolokia 便可将其转换为 HTTP。

什么是Jolokia?

Jolokia 作为目前最主流的 JMX 监控组件,spring 社区(springboot、MVC、cloud)以及目前主流的中间件服务均采用它作为 JMX 监控,Jolokia 是无类型的数据,使用了 Json 这种轻量化的序列化方案来替代 RMI 方案。

Jolokia的特点?

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

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

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

  • 直观来说,Jolokia 就是用于解决 JMX 数据获取时,所遇到的 RMI 协议复杂性、Mbean 查询的不便捷、数据库序列化、MBeanServer 的托管等问题

  • 我们只需要使用 HTTP 请求,直接访问与 WEB 服务相同的 port 即可获取 JMX 数据。

选型考虑

  • 由于在服务端在集群化的弹性环境中,考虑未来微服务下节点大量增长、扩展,并由非常多的应用实例所组成。对于单独节点的监控可能即费力又没有什么实际效果。所以,使用基于时间序列的数据聚合方式将获得更好的效果。
  • Spring Boot & Spring MVC 认可使用 Jolokia 来通过 HTTP 导出 export JMX 数据。只需要在工程类路径中增加一些依赖项,一切都是开箱即用的。不需要任何额外的实现。
  • Telegraf 支持通过整合 Jolokia 来集成 JMX 数据的收集。它有一个预制的输入插件,它是开箱即用的。不需要任何额外的实现。只需要做一些配置即可。
  • InfluxDB 通过输出插件从 Telegraf 接收指标数据,它是开箱即用的,不需要任何额外的实现。
  • Grafana 通过连接 InfluxDB 作为数据源来渲染 Dashboard。它是开箱即用的,不需要额外的实现。

在这里插入图片描述

Jolokia & 服务端集成

Jolokia Agent模式

Agent 可以调用本地的 MBeanServer 暴露 Restful 接口供外部调用,在客户端上可以应用不同的技术来展示通过 Http 获取的 JMX 数据
在这里插入图片描述

Agent模式主要有以下的方式:

  • 方法一:是将 jolokia 放置到 servlet 容器中,比如 Tomcat 或 Jetty,这样 Jolokia 完全可以看做是一个常规的 Java web 应用,让所有的开发人员都能够很好理解并快速的从中读取数据,如下:
[root@localhost webapps]# pwd
/usr/local/src/apache-tomcat-7.0.73/webapps
[root@localhost webapps]# ls -l
total 83428
drwxr-xr-x 14 root root     4096 Jun 28  2018 docs
drwxr-xr-x  7 root root      105 Jun 28  2018 examples
drwxr-xr-x  5 root root       82 Jun 28  2018 host-manager
drwxr-xr-x  4 root root       35 Apr  5  2019 jolokia
-rw-r--r--  1 root root   307617 Nov  9  2014 jolokia.war
drwxr-xr-x  5 root root       97 Jun 28  2018 manager
drwxr-xr-x  3 root root     4096 Jun 28  2018 ROOT
drwxr-xr-x  3 root root       22 Mar 22  2019 v3cAPITestReport
drwxr-xr-x  7 root root     4096 Jun 28  2018 visu1021
-rw-r--r--  1 root root 85103469 Jun 28  2018 visu1021.war

在这里插入图片描述

  • 方法二: 除了放到 Servlet 容器之外,Jolokia 也可以定义特殊的 Agent,比如实现 OSGi 或者内置 Jetty 服务器
  • 方法三:Jolokia 也可以集成到 Web 应用中,jolokia-core 库作为一个 Jar 包,提供一个 Servlet,加入到 Web 应用中之后就可以访问。

考虑到集群部署及目前服务端现状,推荐第三种方式。

jolokia-core 集成示例

SpringMVC

主要步骤:

  1. pom.xml 中增加 jolokia 依赖。
  2. web.xml 中声明 jolokia servlet 启动和适配。
  3. 在 resources 目录下增加 jolokia-access.xml 安全访问
  4. spring xml 文件中增加相关MBean export显示操作。

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

<!-- jolokia 核心组件 -->
	<dependency>
		   <groupId>org.jolokia</groupId>
		   <artifactId>jolokia-core</artifactId>
		   <version>1.6.1</version>
	</dependency>

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

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

<?xml version="1.0" encoding="UTF-8"?>  
<restrict>
 <!-- 若需限制请自行配置 --> 
 <!-- <host>127.0.0.1</host>  --> 
</restrict>

此后,我们将也可以通过如下 http 接口查看 jolokia 的是否正常
在这里插入图片描述

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>  
     
<!-- jolokia 核心组件 -->
	<dependency>
		   <groupId>org.jolokia</groupId>
		   <artifactId>jolokia-core</artifactId>
		   <version>1.6.1</version>
	</dependency>
#jolokia  
management:  
    security:  
        enabled: false  
    address: 127.0.0.1  
endpoints:  
    jolokia:  
        enabled: true  

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

Telegraf 配置

Telegraf 的 Jolokia2 输入插件支持使用 JSON-over-HTTP 协议从一个或多个Jolokia代理REST端点读取JMX指标数据。

[[inputs.jolokia2_agent]]
  urls = ["http://agent:8080/jolokia"]

  [[inputs.jolokia2_agent.metric]]
    name  = "jvm_runtime"
    mbean = "java.lang:type=Runtime"
    paths = ["Uptime"]

每个度量声明生成一个 Jolokia 请求,以便从 JMX MBean 获取指标数据。

Key Required Description
mbean yes JMX MBean 的对象名。MBean 属性键值可以包含通配符 *,允许通过一个声明获取多个 MBean
paths no 要读取的 MBean 属性列表。
tag_keys no 要转换为标记的 MBean 属性键名称列表。属性键名成为标记名,而属性键值成为标记值。
tag_prefix no 在此指标声明生成的标记名称之前的字符串。
field_name no 要设置为由该度量生成的字段的名称的字符串;可以替换。
field_prefix no 在此指标声明产生的字段名之前的字符串;可以替换。

JVM配置如下:

# # Read JMX metrics from a Jolokia REST agent endpoint
[[inputs.jolokia2_agent]]
   urls = ["http://localhost:8089/jolokia"]

[[inputs.jolokia2_agent.metric]]
    name  = "java_runtime"
    mbean = "java.lang:type=Runtime"
    paths = ["Uptime"]

[[inputs.jolokia2_agent.metric]]
    name  = "java_memory"
    mbean = "java.lang:type=Memory"
    paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]

[[inputs.jolokia2_agent.metric]]
    name     = "java_garbage_collector"
    mbean    = "java.lang:name=*,type=GarbageCollector"
    paths    = ["CollectionTime", "CollectionCount"]
    tag_keys = ["name"]

[[inputs.jolokia2_agent.metric]]
    name  = "java_last_garbage_collection"
    mbean = "java.lang:name=*,type=GarbageCollector"
    paths = ["LastGcInfo"]
    tag_keys = ["name"]

[[inputs.jolokia2_agent.metrics]]
    name  = "java_threading"
    mbean = "java.lang:type=Threading"
    paths = ["TotalStartedThreadCount", "ThreadCount", "DaemonThreadCount", "PeakThreadCount"]

[[inputs.jolokia2_agent.metrics]]
    name  = "java_class_loading"
    mbean = "java.lang:type=ClassLoading"
    paths = ["LoadedClassCount", "UnloadedClassCount", "TotalLoadedClassCount"]

[[inputs.jolokia2_agent.metrics]]
    name     = "java_memory_pool"
    mbean    = "java.lang:name=*,type=MemoryPool"
    paths    = ["Usage", "PeakUsage", "CollectionUsage"]
    tag_keys = ["name"]

其他配置可以参考官方示例:
https://github.com/influxdata/telegraf/tree/master/plugins/inputs/jolokia2/examples

InfluxDB 采集的数据如下:

> show measurements
name: measurements
name
----
java_class_loading
java_garbage_collector
java_memory
java_memory_pool
java_runtime
java_threading
> select * from java_memory limit 5
name: java_memory
time                HeapMemoryUsage.committed HeapMemoryUsage.init HeapMemoryUsage.max HeapMemoryUsage.used NonHeapMemoryUsage.committed NonHeapMemoryUsage.init NonHeapMemoryUsage.max NonHeapMemoryUsage.used ObjectPendingFinalizationCount host            jolokia_agent_url
----                ------------------------- -------------------- ------------------- -------------------- ---------------------------- ----------------------- ---------------------- ----------------------- ------------------------------ ----            -----------------
1571105290000000000 3344433152                2147483648           7635730432          1216965408           172425216                    2555904                 -1                     169201160               0                              DESKTOP-MLD0KTS http://localhost:8089/jolokia
1571105300000000000 3344433152                2147483648           7635730432          1287744120           172425216                    2555904                 -1                     168805312               0                              DESKTOP-MLD0KTS http://localhost:8089/jolokia
1571105310000000000 3344433152                2147483648           7635730432          1359803320           172425216                    2555904                 -1                     168981192               0                              DESKTOP-MLD0KTS http://localhost:8089/jolokia
1571105320000000000 3344433152                2147483648           7635730432          1434671784           172425216                    2555904                 -1                     169114552               0                              DESKTOP-MLD0KTS http://localhost:8089/jolokia
1571105330000000000 3344433152                2147483648           7635730432          1509156560           172425216                    2555904                 -1                     169181064               0                              DESKTOP-MLD0KTS http://localhost:8089/jolokia

Grafana监控效果图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

相关资料:

参考资料:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。