spring boot06:Actuator
什么是 Spring Boot Actuator
Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理Spring Boot 应用。这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能都可以通过HTTP 和 JMX 访问。
因为暴露内部信息的特性,Actuator 也可以和一些外部的应用监控系统整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你通过一个统一友好的界面,监视和管理你的应用程序。
Actuator使用Micrometer与这些外部应用程序监视系统集成。这样一来,只需很少的配置即可轻松集成外部的监控系统。
Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只需要使用 Micrometer 的通用 API 来收集性能指标即可。Micrometer 会负责完成与不同监控系统的适配工作。这就使得切换监控系统变得很容易。
对比 Slf4j 之于 Java Logger 中的定位。
MAVEN依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
只要加上了该 maven 依赖,SpringBoot 在运行時就会自动开启/actuator/health和/actuator/info这两个 endpoint,我们就可以透过这两个 endpoint 查看 SpringBoot 运行的情況。
Endpoints
端点,给外部来与应用程序进行访问和交互。
介绍
打比方来说,/health 端点 提供了关于应用健康情况的一些基础信息。/metrics 端点提供了一些有用的应用程序指标(JVM 内存使用、系统CPU使用等)。
这些 Actuator 模块本来就有的端点我们称之为原生端点。根据端点的作用的话,我们大概可以分为三大类:
- 应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring Boot应用密切相关的配置类信息。
- 度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP请求统计等。
- 操作控制类:提供了对应用的关闭等操作类功能。
endpoint 是我们使用 Spring Boot Actuator 最需要关心的对象,列举一些你可能感兴趣的 endpoint
| ID | Description |
|---|---|
| beans | 查看 Spring 容器中的所有对象 |
| configprops | 查看被 @ConfigurationProperties 修饰的对象列表 |
| env | 查看 application.yaml 配置的环境配置信息 |
| health | 健康检查端点 |
| info | 应用信息 |
| metrics | 统计信息 |
| mappings | 服务契约 @RequestMapping 相关的端点 |
| shutdown | 优雅下线 |
例如 health,只需要访问如下 endpoint 即可获取应用的状态
curl "localhost:8080/actuator/health"
了解 endpoint 的 enable 和 exposure 状态
Spring Boot Actuator 针对于所有 endpoint 都提供了两种状态的配置
- enabled 启用状态。默认情况下除了
shutdown之外,其他 endpoint 都是启用状态。这也很好理解,其他 endpoint 基本都是查看行为,shutdown 却会影响应用的运行状态。 - exposure 暴露状态。endpoint 的 enabled 设置为 true 后,还需要暴露一次,才能够被访问,默认情况下只有 health 和 info 是暴露的。
需要注意的就是:
- 每一个端点都可以通过配置来单独禁用或者启动
- enabled 不启用时,相关的 endpoint 的代码完全不会被 Spring 上下文加载,所以 enabled 为 false 时,exposure 配置了也无济于事。
- 不同于Actuator 1.x,Actuator 2.x 的大多数端点默认被禁掉。 Actuator 2.x 中的默认端点增加了
/actuator前缀。默认暴露的两个端点为/actuator/health和/actuator/info
相关配置
我们可以通过以下配置,来配置通过JMX 和 HTTP 暴露的端点。
| Property | Default |
|---|---|
management.endpoints.jmx.exposure.exclude |
|
management.endpoints.jmx.exposure.include |
* |
management.endpoints.web.exposure.exclude |
|
management.endpoints.web.exposure.include |
info, healt |
可以打开所有的监控点
management.endpoints.web.exposure.include=*
也可以选择打开部分,”*” 代表暴露所有的端点,如果指定多个端点,用”,”分开
management.endpoints.web.exposure.exclude=beans,trace
Actuator 默认所有的监控点路径都在/actuator/*,当然如果有需要这个路径也支持定制。
management.endpoints.web.base-path=/minitor
设置完重启后,再次访问地址就会变成/minitor/*。
端点解析
这个部分推荐看官方文档学习,这里就直接放一些最常用的health端点配置信息了
/health端点
/health端点会聚合你程序的健康指标,来检查程序的健康情况。端点公开的应用健康信息取决于:
management.endpoint.health.show-details=always
该属性可以使用以下值之一进行配置:
| Name | Description |
|---|---|
never |
不展示详细信息,up或者down的状态,默认配置 |
when-authorized |
详细信息将会展示给通过认证的用户。授权的角色可以通过management.endpoint.health.roles配置 |
always |
对所有用户暴露详细信息 |
按照上述配置,配置成always之后,我们启动项目,访问http://localhost:8080/actuator/health端口,可以看到这样的信息:

/health端点有很多自动配置的健康指示器:如redis、rabbitmq、db等组件。当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而采集对应的信息。如上面的 diskSpace 节点信息就是DiskSpaceHealthIndicator 在起作用。具体有些哪些健康指示器,这里不做一一介绍了,看官网。
当如上的组件有一个状态异常,应用服务的整体状态即为down。我们也可以通过配置禁用某个组件的健康监测。
management.health.mongo.enabled: false
或者禁用所有自动配置的健康指示器:
management.health.defaults.enabled: false
常用搭配Module
demo-admin-server
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
配置文件:
server:
port: 8000
demo-admin-client
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
配置文件:
server:
port: 8080
servlet:
context-path: /demo
spring:
application:
# Spring Boot Admin展示的客户端项目名,不设置,会使用自动生成的随机id
name: spring-boot-demo-admin-client
boot:
admin:
client:
# Spring Boot Admin 服务端地址
url: "http://localhost:8000/"
instance:
metadata:
# 客户端端点信息的安全认证信息
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
security:
user:
name: xkcoding
password: 123456
management:
endpoint:
health:
# 端点健康情况,默认值"never",设置为"always"可以显示硬盘使用情况和线程情况
show-details: always
endpoints:
web:
exposure:
# 设置端点暴露的哪些内容,默认["health","info"],设置"*"代表暴露所有可访问的端点
include: "*"
运行步骤:
- 进入
spring-boot-demo-admin-server服务端,启动管控台服务端程序 - 进入
spring-boot-demo-admin-client客户端,启动客户端程序,注册到服务端 - 观察服务端里,客户端程序的运行状态等信息

了解 Spring Boot Actuator 的安全风险
从上文的介绍可知,有一些 Spring Boot Actuator 提供的 endpoint 是会将应用重要的信息暴露出去的,以 env 为例来感受下一个典型的 application.yaml 的示例。
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://testDbHost:3306/kirito
username: kirito
password: 123456
kirito:
ak: kirito@xxx_ak
sk: kirito@xxx_sk
management:
endpoints:
web:
exposure:
include: "*"
复制
上面的配置再经典不过,我们看看访问 localhost:8080/actuator/env 之后的返回值
{
"activeProfiles": [],
"propertySources": [
{
"name": "server.ports",
"properties": {
"local.server.port": {
"value": 8080
}
}
},
{
"name": "Config resource 'class path resource [application.yaml]' via location 'optional:classpath:/'",
"properties": {
"server.port": {
"value": 8080,
"origin": "class path resource [application.yaml] - 2:9"
},
"spring.datasource.url": {
"value": "jdbc:mysql://testDbHost:3306/kirito",
"origin": "class path resource [application.yaml] - 5:44"
},
"spring.datasource.username": {
"value": "kirito",
"origin": "class path resource [application.yaml] - 6:15"
},
"spring.datasource.password": {
"value": "******",
"origin": "class path resource [application.yaml] - 7:15"
},
"kirito.ak": {
"value": "kirito@xxx_ak",
"origin": "class path resource [application.yaml] - 10:7"
},
"kirito.sk": {
"value": "kirito@xxx_sk",
"origin": "class path resource [application.yaml] - 11:7"
},
"management.endpoints.web.exposure.include": {
"value": "*",
"origin": "class path resource [application.yaml] - 17:18"
}
}
}
]
}
可以发现,对于内置的敏感配置信息 spring.datasource.password,Spring Boot Actuator 是进行了脱敏的,但是对于自定义的一些敏感配置,如 kirito.ak 和 kirito.sk 却被暴露出来了。
可能有的读者会立马提出质疑:我们的机器都部署内网,并且一般都是通过反向代理对外暴露的服务,这类 endpoint 是不会被外部用户访问到的。那我只能说太天真了,例如以下情况都是导致安全漏洞的真实 case:
- 反向代理误配置了根节点,将 actuator 的 endpoint 和 web 服务一起暴露了出去
- 线上配置没问题,测试环境部署时开通了公网 SLB,导致 actuator 的 endpoint 暴露了出去
- 同一环境中某台机器被攻陷,导致应用配置信息泄露
安全建议
针对 Spring Boot Actuator 提供的 endpoint,采取以下几种措施,可以尽可能降低被安全攻击的风险
- 最小粒度暴露 endpoint。只开启并暴露真正用到的 endpoint,而不是配置:
management.endpoints.web.exposure.include=*。 - 为 endpoint 配置独立的访问端口,从而和 web 服务的端口分离开,避免暴露 web 服务时,误将 actuator 的 endpoint 也暴露出去。例:
management.port=8099。 - 引入
spring-boot-starter-security依赖,为 actuator 的 endpoint 配置访问控制。 - 慎重评估是否需要引入
spring-boot-stater-actuator。以我个人的经验,我至今还没有遇到什么需求是一定需要引入spring-boot-stater-actuator才能解决,如果你并不了解上文所述的安全风险,我建议你先去除掉该依赖。