1、Spring Boot Actuator实现应用监控
前面的例子中,我们学习的都是 Prometheus 自身的内容,即监控的都是机器或者系统层面的指标。那么如果我
们需要对 Java 应用做监控,例如:监控 JVM 的信息,监控 Spring Bean 的信息。那我们应该怎么实现呢?
从这篇文章开始,我们就开始学习如何去监控 Java 应用的状态信息,并且最终实现自定义业务监控指标的监控。
1.1 Spring 监控机制
在学习如何监控 Java 应用之前,我们需要先了解下 SpringBoot 的监控机制。在 Spring 2.x 之前,SpringBoot 使
用 Actuator 模块进行监控,而在 Spring 2.x 之后,SpringBoot 使用了 Micrometer 进行监控。
Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监
控和管理 Spring Boot 应用。这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能都可以通过 HTTP
和 JMX 访问。
在 Spring 2.x 之后,Actuator 使用 Micrometer 与这些外部应用程序监视系统集成。这样一来,只需很少的配置
即可轻松集成外部的监控系统。
那什么是 Micrometer 呢?
Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只需要使用 Micrometer 的通用 API
来收集性能指标即可。Micrometer 会负责完成与不同监控系统的适配工作。这就使得切换监控系统变得很容易。
简单地说,actuator 是真正去采集数据的模块,而 Micrometer 更像是一个适配器,将 actuator 采集到的数据适
合给各种监控工具。
1.2 Spring Actuator 快速入门
接下来我们快速创建一个简单的项目,来让你明白 Spring Boot Actuator 能做什么。
我们到 Spring Initializr 创建一个名为 spring-web-actuator-demo
的项目,配置maven依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-web-actuator-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-web-actuator-demo</name>
<description>Spring Actuator 快速入门</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动文件:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringWebActuatorDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringWebActuatorDemoApplication.class, args);
}
}
打开项目后,直接运行 SpringWebActuatorDemoApplication.java
文件,正常情况下会使用 8080 端口作为服
务端口。
访问 localhost:8080/actuator/health
查看应用的健康状态,正常情况下会返回 UP 信息。
除了提供最基本的健康检查外,actuator 还提供了许多其他的端点(Endpoints)信息。通过这些端点信息,我们
可以掌握 99% 的应用状态信息。
1.3 端点暴露配置
不同于 Actuator 1.x,Actuator 2.x 的大多数端点默认被禁掉。所以在查看对应端点之前,我们需要做好配置,否
则我们是无法访问对应端点的。
我们可以通过以下配置,来配置通过 JMX 和 HTTP 暴露的端点。
属性 | 默认值 |
management.endpoints.jmx.exposure.exclude | |
management.endpoints.jmx.exposure.include | * |
management.endpoints.web.exposure.exclude | |
management.endpoints.web.exposure.include | info, health |
我们可以选择打开所有的监控点,例如:
# 配置
management.endpoints.web.exposure.include=*
也可以选择打开部分端点,例如下面的配置打开 beans 和 trace 两个端点。
management.endpoints.web.exposure.exclude=beans,trace
Actuator 默认所有的监控点路径都在 /actuator/*
,当然如果有需要这个路径也支持定制。例如下面的配置将前
缀改成了 monitor,那么访问路径就变成了 /monitor/*
。
management.endpoints.web.base-path=/monitor
这里我们在 application.properties
中加入如下配置,默认打开所有端点。
management.endpoints.web.exposure.include=*
接着我们访问地址:localhost:8080/actuator/metrics
,可以看到所有的指标地址。
如果我们要查看 process.uptime
指标,那么我们只需要访问
localhost:8080/actuator/metrics/process.uptime
,就可以看到具体的信息。
1.4 常用端点介绍
Spring Boot Actuator 提供了 Endpoints(端点)给外部来与应用程序进行访问和交互。
例如 /health
端点提供了关于应用健康情况的一些基础信息,/metrics
端点提供了一些有用的应用程序指标
(JVM 内存使用、系统 CPU 使用等)。
一般来说,端点可以分为几类:
- 应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与 Spring Boot 应用密切相关的
配置类信息。 - 度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP 请求统计
等。 - 操作控制类:提供了对应用的关闭等操作类功能。详细的原生端点介绍,请以官网为准,这里就不赘述徒增篇
幅。
1.4.1 health 端点
/health
端点会聚合你程序的健康指标,来检查程序的健康情况。端点公开的应用健康信息取决于参数
management.endpoint.health.show-details
,该属性值可选项为:
属性值 | 描述 |
never | 不展示详细信息,up 或者 down 的状态,默认配置 |
when-authorized | 详细信息将会展示给通过认证的用户。授权的角色可以通过 management.endpoint.health.roles 配置 |
always | 对所有用户暴露详细信息 |
接着在 application.properties
中增加如下参数,允许对所有用户暴露详细信息:
# 配置
management.endpoint.health.show-details=always
配置成 always 之后,启动应用,访问 localhost:8080/actuator/health
查看应用的健康状态,正常情况下
会返回 UP 信息。
在这里我们看到除了 status 状态之外,并没有其他信息。
这是因为我们应用中并没有其他依赖。当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而
采集对应的信息。
现在我们在 pom.xml 文件中增加 redis 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
先启动redis,最终我们再次访问地址:localhost:8080/actuator/health
。从图中我们可以看到 redis 的信息
了。
我们也可以通过配置禁用某个组件的健康监测,例如下面的配置禁用了 mongodb 的组件健康监测。
management.health.mongo.enabled: false
或者我们可以禁用所有自动配置的健康指示器:
management.health.defaults.enabled: false
例如在application.properties
文件中配置:
# 配置
management.health.redis.enabled=false
常见的指示器有下面这些:
名称 | 描述 |
CassandraHealthIndicator | 检查Cassandra数据库是否已启动。 |
CouchbaseHealthIndicator | 检查Couchbase群集是否启动。 |
DiskSpaceHealthIndicator | 检查磁盘空间是否不足。 |
DataSourceHealthIndicator | 检查是否可以获取到DataSource的连接。 |
ElasticsearchHealthIndicator | 检查Elasticsearch群集是否启动。 |
InfluxDbHealthIndicator | 检查InfluxDB服务器是否启动。 |
JmsHealthIndicator | 检查JMS代理是否启动。 |
MailHealthIndicator | 检查邮件服务器是否启动。 |
MongoHealthIndicator | 检查Mongo数据库是否已启动。 |
Neo4jHealthIndicator | 检查Neo4j服务器是否启动。 |
RabbitHealthIndicator | 检查Rabbit服务器是否启动。 |
RedisHealthIndicator | 检查Redis服务器是否启动。 |
SolrHealthIndicator | 检查Solr服务器是否启动。 |
除了使用自动引入的健康指示器之外,我们也可以自定义一个 Health Indicator,只需要实现 HealthIndicator 接
口或者继承 AbstractHealthIndicator 类。
例如下面我们创建了一个 CustomHealthIndicator 类,继承了 AbstractHealthIndicator 类,并返回了一些健康信
息。
package com.example;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;
/**
* @author zhangshixing
* @date 2022年03月16日 12:30
*/
@Component
public class CustomHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
// 使用 builder 来创建健康状态信息
// 如果你throw 了一个 exception,那么status 就会被置为DOWN,异常信息会被记录下来
builder.up()
.withDetail("app", "向你报告:项目很健康哦!")
.withDetail("error", "向你报告:项目有点问题哦!");
}
}
我们重启应用并访问地址:localhost:8080/actuator/health
,我们可以看到自定义的健康信息。
1.4.2 metrics 端点
/metrics
端点用来返回当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息、tomcat、
数据库连接池等。当我们访问:localhost:8080/actuator/metrics
时,会返回 SpringBoot Actuator 的所有
可查看端点信息。
我们可以进一步使用如下格式的 URL 访问到对应的信息:
http://localhost:8080/actuator/metrics/{MetricName}
例如我想访问 system.cpu.count
这个指标,那么我访问这个链接即可:
localhost:8080/actuator/metrics/system.cpu.count
,返回值为:
1.4.3 loggers 端点
/loggers
端点暴露了我们程序内部配置的所有 logger 的信息,我们访问这个链接就可以看到:
localhost:8080/actuator/loggers
。
我们也可以通过下述方式访问某一个 logger
http://localhost:8080/actuator/loggers/{name}
例如我想访问 Root Logger
,就可以访问这个链接:localhost:8080/actuator/loggers/ROOT
,返回信息
如下:
1.4.4 info 端点
/info
端点可以用来查看配置文件 application.properties
中 info 节点下的配置信息,默认情况下
application.properties
中并没有 info 节点配置,所以当我们访问 localhost:8080/actuator/info
时
会访问空 JSON 串。
接下来我们在 application.properties
中增加了如下配置:
# 配置
info.app.name=actuator-test-demo
info.app.encoding=UTF-8
info.app.java.source=1.8
info.app.java.target=1.8
再次访问localhost:8080/actuator/info
会返回 info 节点的信息:
同时我们还可以这么配置 info 端点,而不是硬编码这些值,我们就可以按照如下所示的配置:
# 配置
info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@
要注意,info 端点只会返回 info 节点下的信息,而不会返回其他节点下的信息。例如我在配置文件中添加如下配
置:
student.name=ronald
这时候通过 info 端点是访问不到该配置信息的。
1.4.5 beans 端点
/beans
端点会返回 Spring 容器中所有 bean 的别名、类型、是否单例、依赖等信息。
当我们访问 localhost:8080/actuator/beans
时,会返回如下信息:
1.4.6 heapdump 端点
访问 http://localhost:8080/actuator/heapdump
会自动生成一个 JVM 的堆文件 heapdump。
我们可以使用 JDK 自带的 JVM 监控工具 VisualVM 打开此文件查看内存快照。
1.4.7 threaddump 端点
访问 localhost:8080/actuator/threaddump
会返回应用的线程信息,包括线程名、线程 ID、线程的状态、
是否等待锁资源、线程堆栈等信息。
1.4.8 shutdown 端点
这个端点属于操作控制类端点,可以优雅关闭 Spring Boot 应用。要使用这个功能首先需要在配置文件中开启:
# 配置
management.endpoint.shutdown.enabled=true
由于 shutdown 接口默认只支持 POST 请求,我们启动 Demo 项目,向
http://localhost:8080/actuator/shutdown
发起 POST 请求。
远程操作相对来说比较危险,所以一般在线上都不会开启这个端点。
1.5 总结
通过这篇文章,我们了解到 Spring 是利用 Spring Boot Actuator 进行监控指标收集的。与此同时,我们用一个极
简单的例子讲解了如何进行应用监控。最后我们讲解了 Spring Boot Actuator 的端点暴露配置以及常见的端点信
息。