文章目录一、背景二、什么是JMX三、什么是Jolokia四、Jolokia的特点五、选型考虑六、Jolokia 服务端集成1、Jolokia Agent模式2、jolokia-core 集成示例2.1、SpringMVC2.2、SpringBoot七、Telegraf 配置八、Grafana监控效果图一、背景性能测试需要监控服务端 JVM 信息Java 虚拟机 (JVM) 提供操作管理和监测提供了一套完整框架即 JMXJava 管理扩展我们需要做到采集其所暴露出来的性能指标。二、什么是JMXJMX 技术定义了完整的架构和设计模式集合以对 Java 应用进行监测和管理。JMX 的基础是托管豆managed bean业内更习惯将其称为 MBeanMBean 是通过依赖注入完成实例化的各个类别代表着 JVM 中的资源。由于 MBean 代表 JVM 中的资源所以我们可以用其来管理应用的特定方面或者更为常见的一种做法用其来收集与这些资源的使用相关的统计数据。JMX 的核心是 MBean 服务器此类服务器可以作为媒介将 MBean、同一 JVM 内的应用以及外部世界联系在一起。与 MBean 之间的任何交互都是通过此服务器完成的。通常而言只有 Java 代码能够直接访问 JMX API但是有一些适配器可将该 API 转换为标准协议例如 Jolokia 便可将其转换为 HTTP。三、什么是JolokiaJolokia 作为目前最主流的 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 服务端集成1、Jolokia Agent模式Agent 可以调用本地的 MBeanServer 暴露 Restful 接口供外部调用在客户端上可以应用不同的技术来展示通过 Http 获取的 JMX 数据Agent模式主要有以下的方式方法一是将 jolokia 放置到 servlet 容器中比如 Tomcat 或 Jetty这样 Jolokia 完全可以看做是一个常规的 Java web 应用让所有的开发人员都能够很好理解并快速的从中读取数据如下[rootlocalhost webapps]# pwd/usr/local/src/apache-tomcat-7.0.73/webapps[rootlocalhost webapps]# ls -ltotal83428drwxr-xr-x14root root4096Jun282018docs drwxr-xr-x7root root105Jun282018examples drwxr-xr-x5root root82Jun282018host-manager drwxr-xr-x4root root35Apr52019jolokia -rw-r--r--1root root307617Nov92014jolokia.war drwxr-xr-x5root root97Jun282018manager drwxr-xr-x3root root4096Jun282018ROOT drwxr-xr-x3root root22Mar222019v3cAPITestReport drwxr-xr-x7root root4096Jun282018visu1021 -rw-r--r--1root root85103469Jun282018visu1021.war方法二 除了放到 Servlet 容器之外Jolokia 也可以定义特殊的 Agent比如实现 OSGi 或者内置 Jetty 服务器方法三Jolokia 也可以集成到 Web 应用中jolokia-core库作为一个 Jar 包提供一个 Servlet加入到 Web 应用中之后就可以访问。考虑到集群部署及目前服务端现状推荐第三种方式。2、jolokia-core 集成示例2.1、SpringMVC主要步骤pom.xml中增加 jolokia 依赖。在web.xml中声明jolokia servlet启动和适配。在 resources 目录下增加jolokia-access.xml安全访问在spring xml文件中增加相关MBean export显示操作。我们需要在pom.xml中增加 jolokia 的依赖使用最新版本。!-- jolokia 核心组件 --dependencygroupIdorg.jolokia/groupIdartifactIdjolokia-core/artifactIdversion1.6.1/version/dependency需要注意jolokia 作为嵌入式 agent将会与我们 web 容器一起启动jolokia agent 与 web 服务共享一个 HTTP 端口由此 servlet 负责承担请求解析。此后可以通过“/jolokia”来访问内部的 JMX 数据!-- jolokia 监控 --servletservlet-namejolokia‐agent/servlet-nameservlet-classorg.jolokia.http.AgentServlet/servlet-classload-on-startup1/load-on-startup/servletservlet-mappingservlet-namejolokia‐agent/servlet-nameurl-pattern/jolokia/*/url-pattern/servlet-mappingjolokia 以 servlet 服务提供给外部程序那么意味着我们可以通过 URL 获取数据在很多时候我们不希望这些数据被外部非法用户获取、只对内部监控组件开发比如不希望用户通过“域名 /jolokia”来获取数据等。此 jolokia-access.xml 表示只允许127.0.0.1即本地的监控组件可以获取数据对于跨机器、代理程序均无法获取。这也要求我们的telegraf探针是部署在WEB应用的宿主机器上。?xml version1.0 encodingUTF-8?restrict!-- 若需限制请自行配置 --!-- host127.0.0.1/host --/restrict此后我们将也可以通过如下 http 接口查看 jolokia 的是否正常2.2、SpringBootSpringboot 项目对 endpoint 管理更加智能化和全面jmx 的支持很封装也更加完善所以实现 jmx 监控更加便捷。建议关注acturator组件主要步骤pom.xml 中增加 acturator 组件的引入包括 jolokia 组件。利用 springboot 自动装配我们开启“management”、“endpoint”功能即可。我们不再需要web.xml以及jolokia-access.xml因为这些都是默认支持的。自动装配dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!-- jolokia 核心组件 --dependencygroupIdorg.jolokia/groupIdartifactIdjolokia-core/artifactIdversion1.6.1/version/dependency#jolokiamanagement:security:enabled:falseaddress:127.0.0.1endpoints: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]]namejvm_runtimembeanjava.lang:typeRuntimepaths[Uptime]每个度量声明生成一个 Jolokia 请求以便从JMX MBean获取指标数据。KeyRequiredDescriptionmbeanyesJMX MBean 的对象名。MBean 属性键值可以包含通配符 *允许通过一个声明获取多个 MBeanpathsno要读取的 MBean 属性列表。tag_keysno要转换为标记的 MBean 属性键名称列表。属性键名成为标记名而属性键值成为标记值。tag_prefixno在此指标声明生成的标记名称之前的字符串。field_nameno要设置为由该度量生成的字段的名称的字符串可以替换。field_prefixno在此指标声明产生的字段名之前的字符串可以替换。JVM配置如下# # Read JMX metrics from a Jolokia REST agent endpoint[[inputs.jolokia2_agent]]urls[http://localhost:8089/jolokia][[inputs.jolokia2_agent.metric]]namejava_runtimembeanjava.lang:typeRuntimepaths[Uptime][[inputs.jolokia2_agent.metric]]namejava_memorymbeanjava.lang:typeMemorypaths[HeapMemoryUsage,NonHeapMemoryUsage,ObjectPendingFinalizationCount][[inputs.jolokia2_agent.metric]]namejava_garbage_collectormbeanjava.lang:name*,typeGarbageCollectorpaths[CollectionTime,CollectionCount]tag_keys[name][[inputs.jolokia2_agent.metric]]namejava_last_garbage_collectionmbeanjava.lang:name*,typeGarbageCollectorpaths[LastGcInfo]tag_keys[name][[inputs.jolokia2_agent.metrics]]namejava_threadingmbeanjava.lang:typeThreadingpaths[TotalStartedThreadCount,ThreadCount,DaemonThreadCount,PeakThreadCount][[inputs.jolokia2_agent.metrics]]namejava_class_loadingmbeanjava.lang:typeClassLoadingpaths[LoadedClassCount,UnloadedClassCount,TotalLoadedClassCount][[inputs.jolokia2_agent.metrics]]namejava_memory_poolmbeanjava.lang:name*,typeMemoryPoolpaths[Usage,PeakUsage,CollectionUsage]tag_keys[name]其他配置可以参考官方示例https://github.com/influxdata/telegraf/tree/master/plugins/inputs/jolokia2/examplesInfluxDB 采集的数据如下show measurements name: measurements name ---- java_class_loading java_garbage_collector java_memory java_memory_pool java_runtime java_threadingselect* from java_memory limit5name: java_memorytimeHeapMemoryUsage.committed HeapMemoryUsage.init HeapMemoryUsage.max HeapMemoryUsage.used NonHeapMemoryUsage.committed NonHeapMemoryUsage.init NonHeapMemoryUsage.max NonHeapMemoryUsage.used ObjectPendingFinalizationCounthostjolokia_agent_url ---- ------------------------- -------------------- ------------------- -------------------- ---------------------------- ----------------------- ---------------------- ----------------------- ------------------------------ ---- -----------------157110529000000000033444331522147483648763573043212169654081724252162555904-11692011600DESKTOP-MLD0KTS http://localhost:8089/jolokia157110530000000000033444331522147483648763573043212877441201724252162555904-11688053120DESKTOP-MLD0KTS http://localhost:8089/jolokia157110531000000000033444331522147483648763573043213598033201724252162555904-11689811920DESKTOP-MLD0KTS http://localhost:8089/jolokia157110532000000000033444331522147483648763573043214346717841724252162555904-11691145520DESKTOP-MLD0KTS http://localhost:8089/jolokia157110533000000000033444331522147483648763573043215091565601724252162555904-11691810640DESKTOP-MLD0KTS http://localhost:8089/jolokia八、Grafana监控效果图相关资料https://github.com/zuozewei/blog-example/tree/master/Performance-testing/03-performance-monitoring/telegraf-Influxdb-grafana-jmx参考资料[1]https://jolokia.org/reference/html/index.html[2]https://shift-alt-ctrl.iteye.com/blog/2404036[3]http://blog.didispace.com/spring-boot-jolokia-grafana-monitor/[4]https://jolokia.org/reference/html/protocol.html[5]https://github.com/influxdata/telegraf/tree/master/plugins/inputs/jolokia2