Actuator 是 Spring Boot 提供的对应用系统的自省和监控功能。通过 Actuator,可以使用数据化的指标去度量应用的运行情况,比如查看服务器的磁盘、内存、CPU等信息,系统的线程、gc、运行状态等等。
Actuator 通常通过使用 HTTP 和 JMX 来管理和监控应用,大多数情况使用 HTTP 的方式。在spring Boot Admin配合下可以进行页面展示,也和可以与其它外部应用系统系统整合。
一、Actuator 端点说明
端点 | 描述 |
---|---|
auditevents | 获取当前应用暴露的审计事件信息 |
beans | 获取应用中所有的 Spring Beans 的完整关系列表 |
caches | 获取公开可以用的缓存 |
conditions | 获取自动配置条件信息,记录哪些自动配置条件通过和没通过的原因 |
configprops | 获取所有配置属性,包括默认配置,显示一个所有 @ConfigurationProperties 的整理列版本 |
env | 获取所有环境变量 |
flyway | 获取已应用的所有Flyway数据库迁移信息,需要一个或多个 Flyway Bean |
liquibase | 获取已应用的所有Liquibase数据库迁移。需要一个或多个 Liquibase Bean |
health | 获取应用程序健康指标(运行状况信息) |
httptrace | 获取HTTP跟踪信息(默认情况下,最近100个HTTP请求-响应交换)。需要 HttpTraceRepository Bean |
info | 获取应用程序信息 |
integrationgraph | 显示 Spring Integration 图。需要依赖 spring-integration-core |
loggers | 显示和修改应用程序中日志的配置 |
logfile | 返回日志文件的内容(如果已设置logging.file.name或logging.file.path属性) |
metrics | 获取系统度量指标信息 |
mappings | 显示所有@RequestMapping路径的整理列表 |
scheduledtasks | 显示应用程序中的计划任务 |
sessions | 允许从Spring Session支持的会话存储中检索和删除用户会话。需要使用Spring Session的基于Servlet的Web应用程序 |
shutdown | 关闭应用,要求endpoints.shutdown.enabled设置为true,默认为 false |
threaddump | 获取系统线程转储信息 |
heapdump | 返回hprof堆转储文件 |
jolokia | 通过HTTP公开JMX bean(当Jolokia在类路径上时,不适用于WebFlux)。需要依赖 jolokia-core |
prometheus | 以Prometheus服务器可以抓取的格式公开指标。需要依赖 micrometer-registry-prometheus |
二、Actuator的使用与配置
1. 项目依赖
<!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2. 配置文件
在应用启动之后,我们首先访问/actuator
{ "_links": { "self": { "href": "http://localhost:8080/actuator", "templated": false }, "health": { "href": "http://localhost:8080/actuator/health", "templated": false }, "health-path": { "href": "http://localhost:8080/actuator/health/{*path}", "templated": true }, "info": { "href": "http://localhost:8080/actuator/info", "templated": false } } }
从上面可以看到,Spring Boot 2.X 中,Actuator 默认只开放 health 和 info 两个端点。
# false 则禁用所有端点 #management.endpoints.enabled-by-default=true #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info management.endpoints.web.exposure.include=* #设置禁用哪些端点 #management.endpoints.web.exposure.exclude=env,beans #自定义管理端点路径, 默认是/actuator management.endpoints.web.base-path=/manage
注意:Spring Boot 2.x 中的端点和之前的版本有较大不同,启用了不代表可以直接访问,还需要将其暴露出来。
management.endpoints.web.exposure.include=*
management.endpoint.<id>.enabled
3. 常用端点配置
(1) health
主要用来检测应用的运行状况,是使用最多的一个监控点。监控软件通常使用该接口实时监测应用运行状况,在系统出现故障时把报警信息推送给相关人员,如磁盘空间使用情况、数据库和缓存等的一些健康指标。
默认情况下 health 端点是开放的,访问 http://127.0.0.1:8080/actuator/health 即可看到应用运行状态。
{"status":"UP"}
如果需要看到详细信息,则需要做添加配置:
management.endpoint.health.show-details=always
(2) info
查看应用信息是否在 application.properties 中配置。如我们在项目中配置是:
info.app.name=Spring Boot Actuator Demo info.app.version=v1.0.0 info.app.description=Spring Boot Actuator Demo
启动项目,访问 http://127.0.0.1:8080/actuator/info 返回我们刚才配置的信息。
(3) env
通过 env 可以获取到所有关于当前 Spring Boot 应用程序的运行环境信息,如:操作系统信息(systemProperties)、环境变量信息、JDK 版本及 ClassPath 信息、当前启用的配置文件(activeProfiles)、propertySources、应用程序配置信息(applicationConfig)等。
可以通过 http://127.0.0.1:8080/actuator/env/{name} ,name表示想要查看的信息,可以独立显示。
(4) beans
访问 http://127.0.0.1:8080/actuator/beans 会返回信息。从返回的信息中我们可以看出主要展示了 bean 的别名、类型、是否单例、类的地址、依赖等信息。
(5) conditions
通过 conditions 可以在应用运行时查看代码了某个配置在什么条件下生效,或者某个自动配置为什么没有生效。
访问 http://127.0.0.1:8080/actuator/conditions。
(6) loggers
获取系统的日志信息。
访问 http://127.0.0.1:8080/actuator/loggers
(7) mappings
查看所有 URL 映射,即所有 @RequestMapping 路径的整理列表。
访问 http://127.0.0.1:8080/actuator/mappings。
(8) heapdump
访问:http://127.0.0.1:8080/actuator/heapdump会自动生成一个 GZip 压缩的 Jvm 的堆文件 heapdump,我们可以使用 JDK 自带的 Jvm 监控工具 VisualVM 打开此文件查看。
VisualVM下载:https://visualvm.github.io/download.html
(9) threaddump
获取系统线程的转储信息,主要展示了线程名、线程ID、线程的状态、是否等待锁资源等信息。在工作中,我们可以通过查看线程的情况来排查相关问题。
访问 http://127.0.0.1:8080/actuator/threaddump。
(10) shutdown
可以通过 post(仅支持 post) 请求访问 http://127.0.0.1:8080/actuator/shutdown 关闭应用。
(11) metrics
访问 http://127.0.0.1:8080/actuator/metrics 可以获取系统度量指标信息项。
对应访问 names 中的指标,可以查看具体的指标信息。如访问 http://127.0.0.1:8080/actuator/metrics/jvm.memory.used 。
--- JVM --- jvm.memory.max:JVM最大内存 jvm.memory.committed:JVM可用内存,重要。 jvm.memory.used:JVM已用内存,重要。 jvm.buffer.memory.used:JVM缓冲区已用内存。 jvm.buffer.count:当前缓冲区数 jvm.threads.daemon:JVM守护线程数。 jvm.threads.live:JVM当前活跃线程数,重要。 jvm.threads.peak:JVM峰值线程数。 jvm.classes.loaded:加载classes数 jvm.classes.unloaded:未加载的classes数 jvm.gc.memory.allocated:GC时,年轻代分配的内存空间 jvm.gc.memory.promoted:GC时,老年代分配的内存空间 jvm.gc.max.data.size:GC时,老年代的最大内存空间 jvm.gc.live.data.size:FullGC时,老年代的内存空间 jvm.gc.pause:GC耗时 --- TOMCAT --- tomcat.sessions.created:tomcat已创建session数 tomcat.sessions.expired:tomcat已过期session数 tomcat.sessions.active.current:tomcat活跃session数 tomcat.sessions.active.max:tomcat最多活跃session数,重要。 tomcat.sessions.alive.max.second:tomcat最多活跃session数持续时间 tomcat.sessions.rejected:超过session最大配置后,拒绝的session个数。 tomcat.global.error:错误总数。 tomcat.global.sent:发送的字节数 tomcat.global.request.max:request最长时间 tomcat.global.request:全局request次数和时间 tomcat.global.received:全局received次数和时间 tomcat.servlet.request:servlet的请求次数和时间 tomcat.servlet.error:servlet发生错误总数 tomcat.servlet.request.max:servlet请求最长时间 tomcat.threads.busy:tomcat繁忙线程 --- 据此检查是否有线程夯住 tomcat.threads.current:tomcat当前线程数(包括守护线程) tomcat.threads.config.max:tomcat配置的线程最大数 tomcat.cache.access:tomcat读取缓存次数 tomcat.cache.hit:tomcat缓存命中次数 --- CPU --- system.cpu.count:CPU数量 system.load.average.1m:load average system.cpu.usage:系统CPU使用率 process.cpu.usage:当前进程CPU使用率 http.server.requests:http请求调用情况 process.uptime:应用已运行时间 process.files.max:允许最大句柄数 process.start.time:应用启动时间点 process.files.open:当前打开句柄数
三、自定义
上面讲了很多都是配置相关,以及自带的一些端点,在实际应用中有时候默认并不能满足我们的要求,比如Spring Boot
默认的健康端点就很有可能不能满足。
以下是一些HealthIndicator,可以通过management.health.defaults.enabled属性可以禁用它们。
名称 | 描述 |
---|---|
CassandraHealthIndicator |
检查Cassandra 数据库是否启动。 |
DiskSpaceHealthIndicator |
检查磁盘空间不足。 |
DataSourceHealthIndicator |
检查是否可以获得连接DataSource 。 |
ElasticsearchHealthIndicator |
检查Elasticsearch 集群是否启动。 |
InfluxDbHealthIndicator |
检查InfluxDB 服务器是否启动。 |
JmsHealthIndicator |
检查JMS 代理是否启动。 |
MailHealthIndicator |
检查邮件服务器是否启动。 |
MongoHealthIndicator |
检查Mongo 数据库是否启动。 |
Neo4jHealthIndicator |
检查Neo4j 服务器是否启动。 |
RabbitHealthIndicator |
检查Rabbit 服务器是否启动。 |
RedisHealthIndicator |
检查Redis 服务器是否启动。 |
SolrHealthIndicator |
检查Solr 服务器是否已启动。 |
1. 以健康端点health为例
(1) 实现HealthIndicator接口,根据自己的需要判断返回的状态是UP还是DOWN,功能简单。
@Component("my1") public class MyHealthIndicator implements HealthIndicator { private static final String VERSION = "v1.0.0"; @Override public Health health() { int code = check(); if (code != 0) { Health.down().withDetail("code", code).withDetail("version", VERSION).build(); } return Health.up().withDetail("code", code) .withDetail("version", VERSION).up().build(); } private int check() { return 0; } }
(2) 继承AbstractHealthIndicator抽象类,重写doHealthCheck方法,功能比第一种要强大一点点,默认的DataSourceHealthIndicator 、 RedisHealthIndicator都是这种写法,内容回调中还做了异常的处理。
@Component("my2") public class MyAbstractHealthIndicator extends AbstractHealthIndicator { private static final String VERSION = "v1.0.0"; @Override protected void doHealthCheck(Health.Builder builder) throws Exception { int code = check(); if (code != 0) { builder.down().withDetail("code", code).withDetail("version", VERSION).build(); } builder.withDetail("code", code) .withDetail("version", VERSION).up().build(); } private int check() { return 0; } }
2. 定义自己的端点
上面介绍的info、health都是spring-boot-actuator内置的,真正要实现自己的端点还得通过@Endpoint、 @ReadOperation、@WriteOperation、@DeleteOperation。
(1) 注解介绍
不同请求的操作,调用时缺少必需参数,或者使用无法转换为所需类型的参数,则不会调用操作方法,响应状态将为400(错误请求)。
- @Endpoint:构建 rest api 的唯一路径
- @ReadOperation:GET请求,响应状态为 200 如果没有返回值响应 404(资源未找到)
- @WriteOperation:POST请求,响应状态为 200 如果没有返回值响应 204(无响应内容)
- @DeleteOperation:DELETE请求,响应状态为 200 如果没有返回值响应 204(无响应内容)
(2) 使用注解
@Endpoint(id = "harvey") public class MyEndPoint { @ReadOperation public Map<String, String> hello() { Map<String, String> result = new HashMap<>(); result.put("author", "harvey"); result.put("age", "28"); result.put("email", "95735454@qq.com"); return result; } }
完成上面的工作后,SpringBoot对它还不认识,还需要进行配置。
@Configuration public class MyEndpointConfiguration { @Bean @ConditionalOnMissingBean public MyEndPoint myEndPoint() { return new MyEndPoint(); } }
访问:http://localhost:8080/actuator/harvey,展示以下信息则自定义成功。
{ "author": "harvey", "age": "28", "email": "95735454@qq.com" }