Spring Boot(六):Actuator 项目监控 💬

1,541 阅读6分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

Spring Boot Actuator 可以帮助监控和管理 Spring Boot 应用,比如健康检查、审计、统计和 HTTP 追踪等。所有的这些特性可以通过 JMX 或者 HTTP endpoints 来获得。

1. Actuator 监控应用程序

⭐首先要启用 Actuator 的端点,只要在项目中引入 Actuator 的依赖即可:

<!-- SpringBoot项目监控: Spring Boot Actuator -->
<!-- 导入后可以直接在端口进行访问 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

让我们运行应用并且尝试进入默认暴露的 HTTP endpoints

/actuator
/actuator/health
/actuator/health/{component}
/actuator/health/{component}/{instance}
/actuator/info

应用默认使用 8080 端口,一旦应用启动,可以通过 localhost:8080/actuator 访问默认暴露的 HTTP endpoints:

此时打开 http://localhost:8080/actuator/health 便会显示如下内容:

{"status":"UP"}

2. Actuator Endpoints

Spring Boot Actuator 的关键特性是在应用程序里提供众多接口(即 Endpoints),通过它们了解运行时的内部状况。

Actuator Endpoints 允许监视应用程序并与之交互。Spring Boot 包括许多内置端点,并允许定制自己的端点。例如,health endpoint 提供基本应用程序运行状况信息。

2.1 端点列表

ID描述
auditevents暴露当前应用程序的审核事件信息。需要一个 AuditEventRepository组件
beans显示应用程序中所有 Spring Bean 的完整列表。
caches暴露可用的缓存。
conditions显示自动配置的所有条件信息,包括匹配或不匹配的原因。
configprops显示所有 @ConfigurationProperties
env暴露 Spring 的属性 ConfigurableEnvironment
flyway显示已应用的所有Flyway数据库迁移。
需要一个或多个 Flyway 组件。
health显示应用程序运行状况信息。
httptrace显示 HTTP 跟踪信息(默认情况下,最近 100 个 HTTP 请求-响应)。需要一个 HttpTraceRepository 组件。
info显示任意的应用程序信息。
integrationgraph显示 Spring integrationgraph,需要依赖 spring-integration-core
loggers显示和修改应用程序中日志的配置。
liquibase显示已应用的所有 Liquibase 数据库迁移。需要一个或多个 Liquibase 组件。
metrics显示当前应用程序的“指标”信息。
mappings显示所有 @RequestMapping 路径列表。
scheduledtasks显示应用程序中的计划任务。
sessions允许从 Spring Session 支持的会话存储中检索和删除用户会话。需要使用 Spring Session 的基于 Servlet 的 Web 应用程序。
shutdown使应用程序正常关闭,默认禁用。
startup显示由 ApplicationStartup 收集的启动步骤数据。需要使用 SpringApplication 进行配置 BufferingApplicationStartup
threaddump执行线程转储。

如果应用程序是 Web 应用程序(Spring MVC,Spring WebFlux 或 Jersey),还可以使用以下附加端点:

IDDescription
heapdump返回一个 hprof 堆转储文件。需要 HotSpot JVM。
jolokia通过 HTTP 暴露 JMX bean(需要引入 Jolokia,不适用于 WebFlux)。需要引入依赖 jolokia-core
logfile返回日志文件的内容(如果已设置 logging.file.namelogging.file.path 属性)。支持使用 HTTP Range 标头来检索部分日志文件的内容。
prometheus以 Prometheus 服务器可以抓取的格式公开指标。需要依赖 micrometer-registry-prometheus

2.2 暴露所有 Endpoints

Web 默认仅开启几个 endpoints,若要暴露全部的 endpoints,那么需要在 application.yml 进行如下配置:

endpoints:
  web:
    exposure:
      include: '*'

2.3 默认开启所有监控端点&打开/关闭 Actuator Endpoint

management:
  endpoints:
    enabled-by-default: false    # 默认开启所有监控端点:true(此处关闭)

此时,通过 Web 访问就只剩 /actuator

这时,使用 JMX 方式监控同样如此:

关闭默认开启所有监控端点后,我们可以分别暴露选择的端点(同时关闭 management.endpoints.web.exposure.include=*):

management:
  endpoints:
    enabled-by-default: false    # 默认开启所有监控端点:true(此处关闭)
  endpoint:
    health:
      enabled: true
    loggers:
      enabled: true
    mappings:
      enabled: true
    metrics:
      enabled: true

2.4 最常用的 Endpoint

  • Health:监控应用程序状况
  • Metrics:运行时指标
  • Loggers:日志记录

2.4.1 Health Endpoint

/actuator/health endpoint 提供了关于应用健康的基础信息,一般用于云平台,平台会定时检查应用的健康状况,我们就需要 Health Endpoint 为平台返回当前应用的一系列组件健康状况的集合。

显示详细的健康信息
management:
  endpoint:
    health:
      show-details: always  # 开启健康检查的完整信息

2.4.2 Metrics Endpoint

/actuator/metrics/{name} endpoint 展示了几个有用的度量信息,比如 JVM 内存使用情况、系统 CPU 使用情况、打开的文件等等。

访问 localhost:8080/actuator/metrics 可以看到监控指标列表如下:

想要获得某个度量的详细信息,你需要传递度量的名称到 URL 中,例如访问 localhost:8080/actuator/metrics/jvm.memory.used

2.4.3 Loggers Endpoint

/actuator/loggers endpoint 展示了应用的日志并且可以在运行时改变日志等级。

举个例子,为了获得 root logger的细节,你可以访问 http://localhost:8080/actuator/loggers/root:

{
   "configuredLevel":"INFO",
   "effectiveLevel":"INFO"
}
在运行时改变日志等级

loggers endpoint 也允许你在运行时改变应用的日志等级。

举个例子,为了改变 root logger 的等级为 DEBUG ,发送一个 POST 请求到 http://localhost:8080/actuator/loggers/root,加入如下参数:

{
   "configuredLevel": "DEBUG"
}

这个功能对于线上问题的排查非常有用。

同时,你可以通过传递 null 值给 configuredLevel 来重置日志等级。

2.4.4 Info Endpoint

info endpoint 展示了应用的基本信息。它通过 META-INF/build-info.properties 来获得编译信息,通过 git.properties 来获得 Git 信息。它同时可以展示任何其他信息,只要这个环境 property 中含有 info key。

访问 http://localhost:8080/actuator/info

2.4.5 Mappings Endpoint

访问 http://localhost:8080/actuator/mappings 返回请求映射相关信息:

2.4.6 Configprops Endpoint

3. Spring Boot Admin

Spring Boot Admin 是一个开源社区项目,用于管理和监控 Spring Boot 应用程序,提供可视化的 UI 界面展示项目中 Actuator Endpoints 的一些监控信息。

Spring Boot Admin 有两个角色:客户端 (Spring Boot Admin Client) 和服务端 (Spring Boot Admin Server) ;应用程序作为 Spring Boot Admin Client 向 Spring Boot Admin Server 注册!

3.1 Admin-Server

① 创建 admin-server 模块

② 导入依赖坐标 admin-starter-server

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 服务端监控 -->
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
    </dependency>
</dependencies>

配置访问端口:

# 应用名称
spring.application.name=springboot-admin-server
# 应用服务 WEB 访问端口(因为client和server都在同一台电脑上,服务端改成9000端口【区分8080(client默认访问端口)】,访问改端口即可进行监控)
server.port=9000

③ 在引导类上启用监控功能 @EnableAdminServer

// 开启服务端监控
@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootAdminServerApplication.class, args);
    }
}

3.2 Admin-Client

① 创建 admin-client 模块

② 导入坐标依赖 admin-starter-client

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 客户端访问 -->
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-client</artifactId>
    </dependency>
</dependencies>

③ 配置相关信息: server 地址等

# 应用名称
spring.application.name=springboot-admin-client

# 执行admin-server的地址【将该项目的监控信息绑定到本机的9000端口】
# 若admin-server不在本机上,则将localhost改成目标IP
spring.boot.admin.client.url=http://localhost:9000

# server.port=8080       # 访问该项目的端口: 默认8080端口!

# 暴露所有endpoints
management.endpoints.web.exposure.include=*

# 开启健康检查的完整信息(不再只是 UP/DOWN 这样浅显的信息)
management.endpoint.health.show-details=always

④ 同时启动 server 和 client 服务,访问 spring boot admin server 项目端口(http://localhost:9000)

可以观测到有一个实例正在运行:

希望本文对你有所帮助🧠
欢迎在评论区留下你的看法🌊,我们一起讨论与分享🔥