Spring Boot Actuator 的 Prometheus 端点输出的 CPU 负载相关项目
简介
-
- Spring Boot Actuator の prometheus エンドポイントが出力する CPU 負荷関連項目 (CPU使用率など) についてまとめる
- prometheus エンドポイントの出力している値が何を示しているか、Micrometer のソースコードの該当箇所を探す
关于Spring Boot Actuator
Spring Boot Actuator是一个能够通过HTTP等方式获取Spring Boot应用程序的度量信息等功能。
Spring Boot Actuator:生产环境支持功能-文档
在Spring Boot中,包含了许多附加功能,可以在将应用程序推送到生产环境时帮助监视和管理应用程序。您可以选择使用HTTP端点或JMX来管理和监视应用程序。审计、健康和指标收集也可以自动应用于应用程序中。
Spring Boot Actuator: 生产环境适应功能-文件
使用Actuator的终端点可以监控和操作应用程序。Spring Boot内置了许多终端点,并且可以添加自定义终端点。例如:health终端点提供基本的应用程序健康信息。
有关 Prometheus 终端节点
通过访问Spring Boot应用程序的URL路径/actuator/prometheus,可以获取用于Prometheus的输出结果。
Spring Boot Actuator: 生产环境功能 – 文档
使用Prometheus服务器以可被爬取的格式公开指标。需要依赖micrometer-registry-prometheus。
普罗米修斯端点输出的与CPU相关的项目。
系统的CPU数量
表达处理器数量。
Java SE 11及JDK 11 的运行时间
public int availableProcessors()
返回Java虚拟机可以使用的处理器数量。
这个值可能会在虚拟机调用期间发生变化。因此,依赖可用处理器数量的应用程序应该定期轮询该属性,并进行资源使用调整。
返回值:
可用于虚拟机的最大处理器数量。该值永远不会小于1。
/actuator/prometheus 的示例输出。
# HELP system_cpu_count The number of processors available to the Java virtual machine
# TYPE system_cpu_count gauge
system_cpu_count 4.0
系统CPU使用率
表示整个系统的CPU使用率(包括JVM之外的进程)。
操作系统MXBean(Java SE 11和JDK 11)
获取系统整体的”最新CPU使用率”。这是一个在[0.0,1.0]范围内的双精度值。值为0.0表示在最近的监测时段内所有CPU都处于空闲状态,而值为1.0表示在最近的监测时段内所有CPU都一直处于活动状态。根据系统中正在进行的活动,可能会出现从0.0到1.0的任何值。如果无法获取系统的最新CPU使用率,则此方法将返回负值。
返回值:
系统整体的”最新CPU使用率”。如果无法获取,则返回负值。
/actuator/prometheus 的输出示例。
# HELP system_cpu_usage The "recent cpu usage" for the whole system
# TYPE system_cpu_usage gauge
system_cpu_usage 0.8520833333333333
处理器使用率
JVM 的 CPU 使用率。
操作系统MXBean(Java SE 11和JDK 11)
获取进程cpu使用率的方法
此方法返回Java虚拟机进程的“最近的CPU使用率”。这是一个介于[0.0,1.0]之间的双精度值。值为0.0表示在最近的监视期间,没有任何CPU执行JVM进程的线程,值为1.0表示在最近的监视期间,所有的CPU都一直活动并执行JVM的线程。JVM的线程包括JVM的内部线程和应用程序的线程。根据JVM进程和整个系统中的活动情况,可能出现从0.0到1.0的任何值。如果无法获取Java虚拟机的最新CPU使用率,则此方法将返回一个负值。
返回值:
Java虚拟机进程的“最新的CPU使用率”。如果无法获取,则返回负值。
/actuator/prometheus的输出示例。
# HELP process_cpu_usage The "recent cpu usage" for the Java Virtual Machine process
# TYPE process_cpu_usage gauge
process_cpu_usage 0.0191621405839776
系统负载平均值_1分钟
系统负荷平均的最后1分钟。
操作系统MXBean(Java SE 11和JDK 11)。
获取系统的负载平均值。
系统负载平均值是指在可用处理器队列中排队的可执行实体数量和在可用处理器上执行的可执行实体数量的总和,经过一段时间的平均值。负载平均值的计算方法因操作系统而异,通常使用衰减时间依赖平均值。
如果无法获取负载平均值,则返回负值。
该方法旨在提供有关系统负载的提示,并且可以频繁查询。在实现此方法的成本较高的平台上,可能无法使用负载平均值。
返回值:
系统负载平均值。如果不可用,则返回负值。
/actuator/prometheus的输出示例。
# HELP system_load_average_1m The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time
# TYPE system_load_average_1m gauge
system_load_average_1m 11.9169921875
追踪 Micrometer 的源代码
寻找Micrometer源代码中与Prometheus端点输出的值所代表的含义相关的部分。
-
- system.cpu.count → Runtime::availableProcessors
-
- system.load.average.1m → OperatingSystemMXBean::getSystemLoadAverage
-
- system.cpu.usage → OperatingSystemMXBean::getSystemCpuLoad
- process.cpu.usage → OperatingSystemMXBean::processCpuUsage
在io.micrometer.core.instrument.binder.system.ProcessorMetrics类中已设置了获取值的配置。
微米/ProcessorMetrics.java在v1.3.7版本上 · micrometer-metrics/micrometer · GitHub。
/** List of public, exported interface class names from supported JVM implementations. */
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
"com.sun.management.OperatingSystemMXBean", // HotSpot
"com.ibm.lang.management.OperatingSystemMXBean" // J9
);
public ProcessorMetrics(Iterable<Tag> tags) {
this.tags = tags;
this.operatingSystemBean = ManagementFactory.getOperatingSystemMXBean();
this.operatingSystemBeanClass = getFirstClassFound(OPERATING_SYSTEM_BEAN_CLASS_NAMES);
this.systemCpuUsage = detectMethod("getSystemCpuLoad");
this.processCpuUsage = detectMethod("getProcessCpuLoad");
}
@Override
public void bindTo(MeterRegistry registry) {
Runtime runtime = Runtime.getRuntime();
Gauge.builder("system.cpu.count", runtime, Runtime::availableProcessors)
.tags(tags)
.description("The number of processors available to the Java virtual machine")
.register(registry);
if (operatingSystemBean.getSystemLoadAverage() >= 0) {
Gauge.builder("system.load.average.1m", operatingSystemBean, OperatingSystemMXBean::getSystemLoadAverage)
.tags(tags)
.description("The sum of the number of runnable entities queued to available processors and the number " +
"of runnable entities running on the available processors averaged over a period of time")
.register(registry);
}
if (systemCpuUsage != null) {
Gauge.builder("system.cpu.usage", operatingSystemBean, x -> invoke(systemCpuUsage))
.tags(tags)
.description("The \"recent cpu usage\" for the whole system")
.register(registry);
}
if (processCpuUsage != null) {
Gauge.builder("process.cpu.usage", operatingSystemBean, x -> invoke(processCpuUsage))
.tags(tags)
.description("The \"recent cpu usage\" for the Java Virtual Machine process")
.register(registry);
}
}
使用Spring Boot Actuator的示例代码
环境:Java 11 + Spring Boot 2.2.6 + Micrometer Prometheus 1.3.7注册表 + Gradle 6
文件目录
├── build.gradle
├── settings.gradle
└── src
└── main
├── java
│ └── com
│ └── example
│ └── MyApp.java
└── resources
└── application.properties
构建.gradle
为了使用Spring Boot Actuator,需要指定Spring Boot Actuator Starter。
为了输出Prometheus,需要指定Micrometer Registry Prometheus。
plugins {
id 'java'
// Spring Boot Plugin
id 'org.springframework.boot' version '2.2.6.RELEASE'
// Spring Dependency Management Plugin
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}
group = 'com.example'
version = '0.0.1'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
// Spring Boot Web Starter
implementation 'org.springframework.boot:spring-boot-starter-web'
// Spring Boot Actuator Starter
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// Micrometer Registry Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus:1.3.7'
}
settings.gradle 文件
rootProject.name = 'myapp'
src/main/java/com/example/MyApp.java 的路径
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
// シンプルなサンプルアプリケーション
@SpringBootApplication
@RestController
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
@GetMapping("/")
public Map index() {
return Map.of("message", "Hello, world.");
}
}
主要资源/应用程序属性:src/main/resources/application.properties
# Spring Boot Actuator のすべてのエンドポイントをいったん無効にする設定
management.endpoints.enabled-by-default=false
# Prometheus 用のエンドポイントを有効にする設定
management.endpoint.prometheus.enabled=true
management.endpoints.web.exposure.include=prometheus
示例执行案例
在macOS Catalina操作系统上,使用Java 11 (AdoptOpenJDK版本11.0.7+10)和Gradle 6.3启动了Spring Boot应用程序。
$ gradle bootRun
> Task :bootRun
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
用另一个控制台通过以下shell脚本在永久循环中进行访问来增加负载。
#!/bin/sh
while true
do
curl http://localhost:8080/
done
使用另一个控制台通过curl访问Spring Boot Actuator的HTTP端点并获取值。
$ curl http://localhost:8080/actuator
{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"prometheus":{"href":"http://localhost:8080/actuator/prometheus","templated":false}}}
$ curl http://localhost:8080/actuator/prometheus
# HELP process_cpu_usage The "recent cpu usage" for the Java Virtual Machine process
# TYPE process_cpu_usage gauge
process_cpu_usage 0.0191621405839776
# HELP tomcat_sessions_created_sessions_total
# TYPE tomcat_sessions_created_sessions_total counter
tomcat_sessions_created_sessions_total 0.0
# HELP system_cpu_usage The "recent cpu usage" for the whole system
# TYPE system_cpu_usage gauge
system_cpu_usage 0.8520833333333333
# HELP system_cpu_count The number of processors available to the Java virtual machine
# TYPE system_cpu_count gauge
system_cpu_count 4.0
# HELP process_start_time_seconds Start time of the process since unix epoch.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.587801165514E9
# HELP http_server_requests_seconds
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 6.0
http_server_requests_seconds_sum{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.124753781
http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/",} 7040.0
http_server_requests_seconds_sum{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/",} 4.218126
http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator",} 1.0
http_server_requests_seconds_sum{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator",} 0.072301131
# HELP http_server_requests_seconds_max
# TYPE http_server_requests_seconds_max gauge
http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.011892492
http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/",} 0.043555897
http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator",} 0.072301131
# HELP tomcat_sessions_alive_max_seconds
# TYPE tomcat_sessions_alive_max_seconds gauge
tomcat_sessions_alive_max_seconds 0.0
# HELP jvm_buffer_count_buffers An estimate of the number of buffers in the pool
# TYPE jvm_buffer_count_buffers gauge
jvm_buffer_count_buffers{id="mapped",} 0.0
jvm_buffer_count_buffers{id="direct",} 10.0
# HELP jvm_threads_live_threads The current number of live threads including both daemon and non-daemon threads
# TYPE jvm_threads_live_threads gauge
jvm_threads_live_threads 21.0
# HELP jvm_memory_committed_bytes The amount of memory in bytes that is committed for the Java virtual machine to use
# TYPE jvm_memory_committed_bytes gauge
jvm_memory_committed_bytes{area="heap",id="G1 Survivor Space",} 4194304.0
jvm_memory_committed_bytes{area="heap",id="G1 Old Gen",} 5.9768832E7
jvm_memory_committed_bytes{area="nonheap",id="Metaspace",} 4.0660992E7
jvm_memory_committed_bytes{area="nonheap",id="CodeHeap 'non-nmethods'",} 2555904.0
jvm_memory_committed_bytes{area="heap",id="G1 Eden Space",} 9.7517568E7
jvm_memory_committed_bytes{area="nonheap",id="Compressed Class Space",} 5451776.0
jvm_memory_committed_bytes{area="nonheap",id="CodeHeap 'non-profiled nmethods'",} 9502720.0
# HELP process_files_open_files The open file descriptor count
# TYPE process_files_open_files gauge
process_files_open_files 65.0
# HELP tomcat_sessions_active_current_sessions
# TYPE tomcat_sessions_active_current_sessions gauge
tomcat_sessions_active_current_sessions 0.0
# HELP jvm_gc_max_data_size_bytes Max size of old generation memory pool
# TYPE jvm_gc_max_data_size_bytes gauge
jvm_gc_max_data_size_bytes 2.147483648E9
# HELP system_load_average_1m The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time
# TYPE system_load_average_1m gauge
system_load_average_1m 11.9169921875
# HELP jvm_gc_memory_allocated_bytes_total Incremented for an increase in the size of the young generation memory pool after one GC to before the next
# TYPE jvm_gc_memory_allocated_bytes_total counter
jvm_gc_memory_allocated_bytes_total 3.05135616E8
# HELP jvm_buffer_memory_used_bytes An estimate of the memory that the Java virtual machine is using for this buffer pool
# TYPE jvm_buffer_memory_used_bytes gauge
jvm_buffer_memory_used_bytes{id="mapped",} 0.0
jvm_buffer_memory_used_bytes{id="direct",} 81920.0
# HELP process_uptime_seconds The uptime of the Java virtual machine
# TYPE process_uptime_seconds gauge
process_uptime_seconds 250.055
# HELP jvm_gc_live_data_size_bytes Size of old generation memory pool after a full GC
# TYPE jvm_gc_live_data_size_bytes gauge
jvm_gc_live_data_size_bytes 1.0024192E7
# HELP jvm_gc_pause_seconds Time spent in GC pause
# TYPE jvm_gc_pause_seconds summary
jvm_gc_pause_seconds_count{action="end of minor GC",cause="Metadata GC Threshold",} 1.0
jvm_gc_pause_seconds_sum{action="end of minor GC",cause="Metadata GC Threshold",} 0.021
jvm_gc_pause_seconds_count{action="end of minor GC",cause="G1 Evacuation Pause",} 3.0
jvm_gc_pause_seconds_sum{action="end of minor GC",cause="G1 Evacuation Pause",} 0.049
# HELP jvm_gc_pause_seconds_max Time spent in GC pause
# TYPE jvm_gc_pause_seconds_max gauge
jvm_gc_pause_seconds_max{action="end of minor GC",cause="Metadata GC Threshold",} 0.0
jvm_gc_pause_seconds_max{action="end of minor GC",cause="G1 Evacuation Pause",} 0.022
# HELP jvm_classes_unloaded_classes_total The total number of classes unloaded since the Java virtual machine has started execution
# TYPE jvm_classes_unloaded_classes_total counter
jvm_classes_unloaded_classes_total 0.0
# HELP tomcat_sessions_expired_sessions_total
# TYPE tomcat_sessions_expired_sessions_total counter
tomcat_sessions_expired_sessions_total 0.0
# HELP jvm_threads_states_threads The current number of threads having NEW state
# TYPE jvm_threads_states_threads gauge
jvm_threads_states_threads{state="runnable",} 7.0
jvm_threads_states_threads{state="blocked",} 0.0
jvm_threads_states_threads{state="waiting",} 11.0
jvm_threads_states_threads{state="timed-waiting",} 3.0
jvm_threads_states_threads{state="new",} 0.0
jvm_threads_states_threads{state="terminated",} 0.0
# HELP process_files_max_files The maximum file descriptor count
# TYPE process_files_max_files gauge
process_files_max_files 10240.0
# HELP tomcat_sessions_rejected_sessions_total
# TYPE tomcat_sessions_rejected_sessions_total counter
tomcat_sessions_rejected_sessions_total 0.0
# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Survivor Space",} 4194304.0
jvm_memory_used_bytes{area="heap",id="G1 Old Gen",} 1.0024192E7
jvm_memory_used_bytes{area="nonheap",id="Metaspace",} 3.907744E7
jvm_memory_used_bytes{area="nonheap",id="CodeHeap 'non-nmethods'",} 1185920.0
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 1.8874368E7
jvm_memory_used_bytes{area="nonheap",id="Compressed Class Space",} 4839600.0
jvm_memory_used_bytes{area="nonheap",id="CodeHeap 'non-profiled nmethods'",} 9437696.0
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
jvm_classes_loaded_classes 6995.0
# HELP tomcat_sessions_active_max_sessions
# TYPE tomcat_sessions_active_max_sessions gauge
tomcat_sessions_active_max_sessions 0.0
# HELP jvm_gc_memory_promoted_bytes_total Count of positive increases in the size of the old generation memory pool before GC to after GC
# TYPE jvm_gc_memory_promoted_bytes_total counter
jvm_gc_memory_promoted_bytes_total 7294864.0
# HELP jvm_memory_max_bytes The maximum amount of memory in bytes that can be used for memory management
# TYPE jvm_memory_max_bytes gauge
jvm_memory_max_bytes{area="heap",id="G1 Survivor Space",} -1.0
jvm_memory_max_bytes{area="heap",id="G1 Old Gen",} 2.147483648E9
jvm_memory_max_bytes{area="nonheap",id="Metaspace",} -1.0
jvm_memory_max_bytes{area="nonheap",id="CodeHeap 'non-nmethods'",} 6975488.0
jvm_memory_max_bytes{area="heap",id="G1 Eden Space",} -1.0
jvm_memory_max_bytes{area="nonheap",id="Compressed Class Space",} 1.073741824E9
jvm_memory_max_bytes{area="nonheap",id="CodeHeap 'non-profiled nmethods'",} 2.44682752E8
# HELP logback_events_total Number of error level events that made it to the logs
# TYPE logback_events_total counter
logback_events_total{level="warn",} 0.0
logback_events_total{level="debug",} 0.0
logback_events_total{level="error",} 0.0
logback_events_total{level="trace",} 0.0
logback_events_total{level="info",} 7.0
# HELP jvm_threads_peak_threads The peak live thread count since the Java virtual machine started or peak was reset
# TYPE jvm_threads_peak_threads gauge
jvm_threads_peak_threads 21.0
# HELP jvm_threads_daemon_threads The current number of live daemon threads
# TYPE jvm_threads_daemon_threads gauge
jvm_threads_daemon_threads 17.0
# HELP jvm_buffer_total_capacity_bytes An estimate of the total capacity of the buffers in this pool
# TYPE jvm_buffer_total_capacity_bytes gauge
jvm_buffer_total_capacity_bytes{id="mapped",} 0.0
jvm_buffer_total_capacity_bytes{id="direct",} 81920.0
参考资料
-
- Spring Boot Actuator: Production-ready Features
-
- Spring Boot Actuator: 本番対応機能 – ドキュメント
- Micrometer Application Monitoring