Actuator 端点
本教程共 48 篇 · 第 36 篇 · 更新于 2026-08-13 · 约 5 分钟阅读
本节目标:引入并暴露 Actuator 端点,认识常用端点,掌握 4.x 的端点访问控制,学会给端点加安全保护。
Actuator 是什么
应用上线后,怎么知道它活着?内存多少?配置对不对?日志级别能改吗?
Actuator 把这些能力做成了现成端点。加一个依赖,应用就长出「体检窗口」。
它从 2014 年 Spring Boot 1.0 就存在,是「生产就绪」特性的核心。运维要的东西,大多不用自己写。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
启动后访问 http://localhost:8080/actuator,能看到端点发现页(_links),列出当前可用的所有端点。
默认只暴露 health 一个端点。这是刻意设计:端点可能泄露敏感信息,宁缺毋滥。
暴露端点
用 management.endpoints.web.exposure.include 控制 HTTP 暴露:
management:
endpoints:
web:
exposure:
include: "health,info,metrics,env,beans,loggers"
全部暴露用 "*",再排除个别:
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env,beans"
WarningYAML 里
*有特殊含义,必须加引号。公开部署时别全量暴露,先想清楚哪些端点能见人。
常用端点速览
| 端点 | 作用 | 方法 |
|---|---|---|
/actuator/health | 应用健康状态 | GET |
/actuator/info | 自定义应用信息 | GET |
/actuator/env | 环境属性(敏感值脱敏) | GET |
/actuator/metrics | 指标列表与查询 | GET |
/actuator/beans | 所有 Spring Bean 清单 | GET |
/actuator/conditions | 自动配置命中条件 | GET |
/actuator/mappings | 所有 URL 映射 | GET |
/actuator/loggers | 查看/修改日志级别 | GET/POST |
/actuator/threaddump | 线程转储 | GET |
/actuator/heapdump | 堆转储文件 | GET |
/actuator/httpexchanges | 最近 100 条 HTTP 交换记录 | GET |
/actuator/shutdown | 优雅停机(默认禁用) | POST |
动手试几个:
curl http://localhost:8080/actuator/health
curl http://localhost:8080/actuator/metrics
curl http://localhost:8080/actuator/metrics/jvm.memory.used
几个端点的使用场景:
health:监控系统轮询它,挂了发告警env:排查「配置怎么跟预期不一样」,注意敏感值会打码beans:怀疑 Bean 没装上,看它有没有出现conditions:自动配置为什么没生效,看条件报告loggers:线上临时调日志级别,不用重启threaddump:应用卡死时抓线程栈,看锁在哪
info 端点:应用自我介绍
/actuator/info 默认是空的。往里填内容有三种方式:
info:
app:
name: "order-service"
version: "1.2.0"
contact:
email: "ops@example.com"
构建信息(Maven 插件生成 META-INF/build-info.properties)和 Git 提交信息(git-commit-id 插件)也能自动进来。值班的人打开 info 就知道该找谁。
端点访问控制(4.x 新模型)
Spring Boot 4 起,端点在「暴露」之外新增了「访问级别」。取值三个:
unrestricted:完全放开read-only:只允许读操作none:禁止访问
默认除了 shutdown、heapdump 之外全部 unrestricted。想收紧,用属性控制:
management:
endpoints:
access:
default: none # 默认谁都不给访问
endpoint:
loggers:
access: read-only # loggers 只读
shutdown:
access: unrestricted # shutdown 单独放开
Note访问级别和暴露是两回事:暴露决定「端点有没有注册到 HTTP」,访问级别决定「能不能调」。4.x 之前只有暴露这一层开关,现在多了一道闸。
端点安全
端点暴露了不代表裸奔。生产环境三件套:
- 只暴露必要的端点
- 用 Spring Security 保护
- 或放到独立管理端口
独立管理端口,只监听内网:
management:
server:
port: 8081
address: 127.0.0.1
Note版本对照:2.x 的
management.port、management.security.enabled早已移除。现在是management.server.port,安全性交给 Spring Security,而不是一个开关。
配合 Spring Security 的完整示例:
package com.example.demo.config;
import org.springframework.boot.security.autoconfigure.actuate.web.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
public class ActuatorSecurityConfig {
@Bean
public SecurityFilterChain actuatorFilterChain(HttpSecurity http) throws Exception {
http
.securityMatcher(EndpointRequest.toAnyEndpoint())
.authorizeHttpRequests(auth -> auth.anyRequest().hasRole("ENDPOINT_ADMIN"))
.httpBasic(withDefaults());
return http.build();
}
}
独立管理端口的另一个好处:应用主端口挂了,管理端口可能还活着,健康检查能区分「应用挂了」和「网络断了」。但注意,独立端口用的是另一套 Web 基础设施,探针也可能误判,K8s 场景常用 add-additional-paths 把探针挂到主端口(见下一节)。
敏感值脱敏
/actuator/env、/actuator/configprops 会显示配置值。密码、密钥默认打码成 ******。需要管理员看原文:
management:
endpoint:
env:
show-values: when-authorized
roles: "admin"
show-values 取值:
never:默认,永远打码always:所有人可见when-authorized:只有指定角色可见
JMX 与 shutdown 端点
除了 HTTP,端点还能走 JMX 暴露:management.endpoints.jmx.exposure.include,默认也是 health。本地用 JConsole 就能看,适合没有 HTTP 暴露的内网场景。
shutdown 端点演示优雅停机:
management:
endpoint:
shutdown:
access: unrestricted
curl -X POST http://localhost:8080/actuator/shutdown
应用收到关闭信号,走完销毁流程再退出。注意它只在 jar 打包方式下生效,生产环境别开。
定制路径与缓存
不想用 /actuator 前缀,可以改:
management:
endpoints:
web:
base-path: "/manage"
path-mapping:
health: "healthcheck"
改完后 health 端点变成 /manage/healthcheck。
Note路径的相对基准:没配独立管理端口时,base-path 相对
server.servlet.context-path;配了management.server.port,就相对管理端口的 base-path。
端点对无参读操作有缓存,改 TTL:
management:
endpoint:
beans:
cache:
time-to-live: 10s
自定义端点
内置端点不够用时,可以用注解自己造一个:
package com.example.demo.actuator;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@WebEndpoint(id = "maintenance")
public class MaintenanceEndpoint {
private boolean maintenanceMode = false;
@ReadOperation
public Map<String, Object> status() {
return Map.of("maintenance", maintenanceMode);
}
@WriteOperation
public void toggle(boolean enabled) {
this.maintenanceMode = enabled;
}
}
@ReadOperation 对应 GET,@WriteOperation 对应 POST。定义后自动出现在 /actuator/maintenance,同样受暴露和访问级别控制。
初学者常栽的坑
- YAML 里
include: "*"忘加引号:*被当成锚点语法,配置直接解析失败 - 以为暴露了就能访问:4.x 还有
access这道闸,access: none的端点暴露了也调不了 - 生产开着 shutdown:任何人 POST 一下,应用就没了
- 管理端口和主端口搞混:配置写错端口,探针打到主端口 404
- 全量暴露后忘了脱敏:
env端点能看到一堆配置,先确认show-values和角色
本节小结
spring-boot-starter-actuator引入监控端点,默认只暴露 healthmanagement.endpoints.web.exposure.include控制暴露清单- 4.x 用
management.endpoint.<id>.access控制访问级别(unrestricted/read-only/none) - 安全三件套:最小暴露 + Spring Security + 独立管理端口
- env 等端点敏感值默认脱敏,
show-values控制可见性 @WebEndpoint+@ReadOperation可以自定义端点