性能監控之Telegraf+InfluxDB+Grafana實現JMX實時監控

背景

性能測試需要監控服務端 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監控效果圖

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

相關資料:
https://github.com/zuozewei/PerformanceTest-Examples/tree/master/Performance%20Monitoring/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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章