Spring Boot Actuator
Spring Boot Actuator 通过管理端点提供应用运行状态和诊断信息。本文以 Boot 3.5 为准,先说明端点怎样暴露和鉴权,再区分存活与就绪探针。最后介绍启动耗时分析,以及不同故障应选择的诊断入口。
1. 面试核心
先记住这几条,再读正文- 端点暴露。
management.endpoints.web.exposure.include决定 HTTP 暴露范围。 - 探针职责。 平台在 liveness 连续失败后重启实例,在 readiness 失败后停止向该实例转发流量。卡 · 常用端点
- 默认健康组。 Boot 默认的 liveness 与 readiness 健康组分别只检查应用发布的存活状态和就绪状态。
- 启动步骤采集。
BufferingApplicationStartup为startup端点采集启动步骤。 - 探测路径。 独立管理端口上的探针成功,只能证明管理服务路径可用。卡 · 业务端口探针
2. 常用端点
端点是供监控或运维工具调用的管理接口。不同端点回答不同问题,使用前可以按下表选择。
| 端点 | 信息 |
|---|---|
health | 组件健康状态与健康组 |
metrics、prometheus | 指标查询与 Prometheus 抓取 |
conditions | 自动配置匹配报告 |
configprops、env | 配置绑定与属性来源 |
beans、mappings | Bean 与 Web 路由 |
startup | 启动步骤 |
loggers | 日志级别查询与调整 |
threaddump、heapdump | 线程与堆诊断 |
metrics 用于查询指标名称、标签和值,prometheus 则提供监控系统可抓取的格式。后者需要 micrometer-registry-prometheus 依赖。Boot 3.5 默认只通过 HTTP 暴露 health,其他端点要按需开放。
3. 端点暴露与访问控制
开放端点前,需要分别确定操作权限、网络暴露和请求鉴权:
- 操作权限决定端点允许读取还是修改状态。
- 网络暴露决定端点能否通过 HTTP 等方式访问。
- 请求鉴权决定哪些调用方有权访问端点。
下面的配置声明 HTTP 暴露范围,并限制健康详情的展示:
management:
endpoints:
web:
exposure:
include: health,info,prometheus
endpoint:
health:
show-details: when_authorized
示例通过 include 暴露 health、info 和 prometheus。show-details: when_authorized 让健康详情只对获授权的调用方展示。具体的认证与授权仍由安全过滤链负责,也就是在请求到达端点前检查身份和权限。
Boot 3.5 用 management.endpoint.<id>.access 限制操作,支持三种取值:
none禁止访问该端点。read-only只允许读取操作。unrestricted允许端点提供的读取和写入操作。
自定义 SecurityFilterChain 后,Boot 的管理端点安全配置退让。应用需要显式配置这些端点的访问规则。
生产环境只向探针和监控系统开放所需端点。其他诊断端点可以放在独立管理端口或受控内网,并配置认证。临时运维访问也要按权限开放。
env、configprops、堆转储和线程栈会暴露内部信息。例如其中会包含地址、类名、查询、令牌或用户数据。因此,获取或分享这些结果前,要核对脱敏效果和访问权限,尤其检查自定义属性。
4. Liveness 探针
Liveness 是存活探针,用于判断应用内部是否已经陷入无法自行恢复的状态。平台在连续探测失败后重启实例,尝试恢复服务。
数据库、缓存和远程 API 的故障应由连接超时、重试或降级处理。重启本地进程无法恢复这些外部服务。若把共享依赖加入 liveness,一次依赖故障就会触发所有实例反复重启,形成重启风暴。
Boot 的 LivenessStateHealthIndicator 读取应用发布的可用性状态。线程死锁和关键内部状态损坏,需要专门的检测逻辑。发现这类问题后,应用可发布存活状态变化,或增加对应健康检查。
5. Readiness 探针
Readiness 是就绪探针,用于判断实例当前是否应接收流量。启动尚未完成、正在优雅下线或关键能力暂时不可用时,实例可以拒绝流量。平台随后停止向它转发请求,进程仍可继续运行或完成清理。
Boot 的默认 readiness 组只包含 readinessState,也就是应用发布的就绪状态。
外部依赖是否加入该组,要看服务的降级能力。所有请求都依赖数据库时,可加入数据库检查。若数据库断开后仍能提供缓存读取、静态接口或排队能力,就要按这些能力设计就绪判断。否则,共享依赖故障会使全部实例同时退出流量,连仍可提供的功能也无法使用。
两类探针都要分别设置超时、探测周期和失败阈值,并给正常抖动留出余量。参数过于激进,会把短暂等待变成重启或摘流。启动较慢时,可用平台的 startup probe,也就是启动探针,保护启动阶段。
6. 启动阶段分析
分析启动慢时,需要知道时间花在哪个阶段。先为应用设置启动记录器,保存各步骤的耗时:
SpringApplication app = new SpringApplication(OrderApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);
配置后,再按需暴露 startup 端点,就能查看已采集的启动步骤。也可改用 FlightRecorderApplicationStartup,把启动事件写入 JFR。JFR 是 JVM 的事件记录工具,可把启动过程与类加载、对象分配和 GC 事件关联起来。
诊断时,按以下五个阶段拆分耗时:
- 检查配置数据读取和条件评估花了多久。
- 检查 BeanDefinition 处理,也就是容器解析和调整对象定义的耗时。
- 检查 Bean 创建与生命周期回调是否等待外部操作。
- 分别检查 Web 服务器、数据库迁移和连接池初始化。
- 为 Runner 和自定义预热单独计时。
Runner 是 Boot 在上下文刷新后执行的启动任务。记录器只包含实际埋点的操作,所以业务代码的耗时还需自行补充。这样才能区分框架处理、业务初始化和外部依赖等待。
7. 诊断端点选择
先明确要验证的故障原因,再选择能提供证据的端点。常见问题可以按以下诊断入口排查:
- Bean 缺失时,查看
conditions与beans。 - 配置值异常时,查看
env与configprops,追踪 PropertySource 中的属性来源。 - 路由缺失时,查看
mappings。 - 延迟或错误率上升时,结合指标、trace ID 和请求日志定位异常请求。
- 线程阻塞时,连续获取线程转储并比较调用栈。
- 内存持续增长时,先观察 GC,再按需获取堆转储。
trace ID 是一次请求链路的关联标识,可用来查找同一请求的日志。堆转储会增加诊断开销,应在资源允许时执行。按问题逐步取证,能避免同时下载大量诊断结果给服务增加负载。
8. 业务端口探针
配置独立管理端口后,还需要检查探针是否经过业务流量的接入路径。两个端口有各自的连接和请求处理路径,所以管理端口响应成功时,业务端口仍可处于阻塞状态。
management:
endpoint:
health:
probes:
enabled: true
add-additional-paths: true
Boot 3.5 使用上述配置在主端口增加 /livez 与 /readyz。健康组原路径仍是 /actuator/health/liveness 和 /actuator/health/readiness。平台探测主端口,才能覆盖业务端口的接入路径。
健康状态为 DOWN 或 OUT_OF_SERVICE 时,默认返回 HTTP 503。自定义状态映射时,应保留这两个失败映射。
9. 常见问题
9.1 health 返回 UP 就能证明业务正常吗?
UP 只表示已注册的健康检查通过。数据库可连接后,查询结果、权限、数据延迟和业务规则仍可能有问题。判断业务是否正常,还要结合业务指标和真实请求错误率。
可以再用低频合成请求覆盖关键业务路径。合成请求是监控系统主动发出的测试请求,用于验证一条业务流程能否完成。
9.2 健康检查应该执行真实 SQL 吗?
可以执行有超时的轻量连通性查询。高频探针应避免复杂查询和业务关键锁竞争,否则检查本身就会增加请求延迟。更深入的校验可以放在低频合成监控中,并设置独立超时和容量限制。
10 · 面试题卡片
10.1 Spring Boot 服务怎样设计健康检查
出现公司:交通银行
考察重点:解释存活与就绪失败后的不同处置,并根据降级能力选择依赖检查。说明端点暴露与鉴权分别控制什么。
参考回答
健康检查应分别用 liveness 判断是否需要重启,用 readiness 判断是否接收流量。
默认健康组读取应用可用性状态。外部依赖故障交给 readiness 按降级能力判断,避免一次依赖故障触发所有实例重启。两类探针分别设置超时、周期和失败阈值。
使用 management.endpoints.web.exposure.include 暴露必要端点,再由安全过滤链鉴权。健康详情按权限展示,敏感诊断端点放在受控管理网络。还要从业务端口探测接入路径,并结合业务指标和合成请求判断实际服务能力。
10.2 管理端口健康时,业务端口一定可用吗?
出现公司:暂无已核验的公开来源(本站自测)
考察重点:说明独立管理端口为何会漏掉业务接入故障,以及健康组如何用 HTTP 状态表达失败。
相关内容:业务端口探针。
参考回答
不一定,两个端口有独立的请求处理路径,管理端口成功时业务端口仍会阻塞。
可以配置 management.endpoint.health.probes.add-additional-paths=true,在主端口提供 /livez 与 /readyz。平台探测主端口后,才能发现该路径的接入故障。健康组为 DOWN 或 OUT_OF_SERVICE 时,默认返回 HTTP 503,供平台识别失败。