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 信息。

调用链如何监控 SpringBoot springboot接口监控_spring

除了提供最基本的健康检查外,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,可以看到所有的指标地址。

调用链如何监控 SpringBoot springboot接口监控_prometheus_02

如果我们要查看 process.uptime 指标,那么我们只需要访问

localhost:8080/actuator/metrics/process.uptime,就可以看到具体的信息。

调用链如何监控 SpringBoot springboot接口监控_spring_03

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 信息。

调用链如何监控 SpringBoot springboot接口监控_prometheus_04

在这里我们看到除了 status 状态之外,并没有其他信息。

这是因为我们应用中并没有其他依赖。当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而

采集对应的信息。

现在我们在 pom.xml 文件中增加 redis 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

先启动redis,最终我们再次访问地址:localhost:8080/actuator/health。从图中我们可以看到 redis 的信息

了。

调用链如何监控 SpringBoot springboot接口监控_java_05

我们也可以通过配置禁用某个组件的健康监测,例如下面的配置禁用了 mongodb 的组件健康监测。

management.health.mongo.enabled: false

或者我们可以禁用所有自动配置的健康指示器:

management.health.defaults.enabled: false

例如在application.properties文件中配置:

# 配置
management.health.redis.enabled=false

调用链如何监控 SpringBoot springboot接口监控_spring boot_06

常见的指示器有下面这些:

名称

描述

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,我们可以看到自定义的健康信息。

调用链如何监控 SpringBoot springboot接口监控_java_07

1.4.2 metrics 端点

/metrics 端点用来返回当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息、tomcat、

数据库连接池等。当我们访问:localhost:8080/actuator/metrics 时,会返回 SpringBoot Actuator 的所有

可查看端点信息。

调用链如何监控 SpringBoot springboot接口监控_调用链如何监控 SpringBoot_08

我们可以进一步使用如下格式的 URL 访问到对应的信息:

http://localhost:8080/actuator/metrics/{MetricName}

例如我想访问 system.cpu.count 这个指标,那么我访问这个链接即可:

localhost:8080/actuator/metrics/system.cpu.count,返回值为:

调用链如何监控 SpringBoot springboot接口监控_spring boot_09

1.4.3 loggers 端点

/loggers 端点暴露了我们程序内部配置的所有 logger 的信息,我们访问这个链接就可以看到:

localhost:8080/actuator/loggers

调用链如何监控 SpringBoot springboot接口监控_spring boot_10

我们也可以通过下述方式访问某一个 logger

http://localhost:8080/actuator/loggers/{name}

例如我想访问 Root Logger,就可以访问这个链接:localhost:8080/actuator/loggers/ROOT,返回信息

如下:

调用链如何监控 SpringBoot springboot接口监控_prometheus_11

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 节点的信息:

调用链如何监控 SpringBoot springboot接口监控_调用链如何监控 SpringBoot_12

同时我们还可以这么配置 info 端点,而不是硬编码这些值,我们就可以按照如下所示的配置:

# 配置
info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@

调用链如何监控 SpringBoot springboot接口监控_prometheus_13

要注意,info 端点只会返回 info 节点下的信息,而不会返回其他节点下的信息。例如我在配置文件中添加如下配

置:

student.name=ronald

这时候通过 info 端点是访问不到该配置信息的。

1.4.5 beans 端点

/beans 端点会返回 Spring 容器中所有 bean 的别名、类型、是否单例、依赖等信息。

当我们访问 localhost:8080/actuator/beans 时,会返回如下信息:

调用链如何监控 SpringBoot springboot接口监控_spring boot_14

1.4.6 heapdump 端点

访问 http://localhost:8080/actuator/heapdump 会自动生成一个 JVM 的堆文件 heapdump。

调用链如何监控 SpringBoot springboot接口监控_spring_15

我们可以使用 JDK 自带的 JVM 监控工具 VisualVM 打开此文件查看内存快照。

1.4.7 threaddump 端点

访问 localhost:8080/actuator/threaddump 会返回应用的线程信息,包括线程名、线程 ID、线程的状态、

是否等待锁资源、线程堆栈等信息。

调用链如何监控 SpringBoot springboot接口监控_prometheus_16

1.4.8 shutdown 端点

这个端点属于操作控制类端点,可以优雅关闭 Spring Boot 应用。要使用这个功能首先需要在配置文件中开启:

# 配置
management.endpoint.shutdown.enabled=true

由于 shutdown 接口默认只支持 POST 请求,我们启动 Demo 项目,向

http://localhost:8080/actuator/shutdown 发起 POST 请求。

调用链如何监控 SpringBoot springboot接口监控_调用链如何监控 SpringBoot_17

远程操作相对来说比较危险,所以一般在线上都不会开启这个端点。

1.5 总结

通过这篇文章,我们了解到 Spring 是利用 Spring Boot Actuator 进行监控指标收集的。与此同时,我们用一个极

简单的例子讲解了如何进行应用监控。最后我们讲解了 Spring Boot Actuator 的端点暴露配置以及常见的端点信

息。