Monitoring Spring Boot with Nightingale: Actuator Metrics, Categraf Scraping and JVM Dashboards
Nightingale 官方仓库(integrations/SpringBoot/markdown/README.en_US.md)为 Spring Boot 应用提供了一套"开箱即用"的监控接入方案:应用侧使用 Spring Boot Actuator(底层基于 Micrometer)暴露 Prometheus 格式指标,采集侧由 Categraf 的 Prometheus 插件抓取并上送 Nightingale,最后配合仓库内置的 JVM 仪表盘与告警规则完成可观测闭环。读完本文,你将掌握 Spring Boot 2.x/3.x 的指标暴露配置、Categraf 采集配置的每个参数含义,以及如何导入现成的 JVM 监控仪表盘和五条常用告警规则。
Spring Boot 为什么直接用 Actuator 而不是裸 Micrometer
Java 生态中,暴露 metrics 数据通常会选择 Micrometer。但对 Spring Boot 项目而言,更简单的做法是直接用 Spring Boot Actuator:Actuator 底层同样基于 Micrometer 实现,只是把指标收集、注册与 HTTP 暴露这些繁琐细节全部封装好了,开发者只需要添加两个依赖并做少量配置即可。
要启用指标暴露,在 pom.xml 中引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
spring-boot-starter-actuator:提供 Actuator 的 Web 端点(/actuator/*)与 Micrometer 指标注册能力;micrometer-registry-prometheus:把 Micrometer 指标注册表以 Prometheus 文本格式输出,供采集器抓取。
应用配置:按 Spring Boot 版本区分
Spring Boot 3.x
在 application.properties 中加入:
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.prometheus.metrics.export.enabled=true
Spring Boot 2.x
在 application.properties 中加入:
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true
两个版本唯一的区别在于第 3 行配置的路径:3.x 使用 management.prometheus.metrics.export.enabled,2.x 使用 management.metrics.export.prometheus.enabled,含义相同——开启 Prometheus 导出。
启动后验证
应用启动后,在浏览器或命令行确认指标端点可访问:
curl -fsS http://localhost:8080/actuator/prometheus | head
能看到 jvm_memory_used_bytes、http_server_requests_seconds_*、logback_events_total 等以 _total/_seconds 结尾的指标即说明暴露成功。指标端点正常工作后,/actuator/prometheus 才能被采集器抓取到数据。
安全提示:除非确有需要,不要把
management.endpoints.web.exposure.include设置为*(暴露全部 Actuator 端点)。只暴露health、info、prometheus这类监控必需端点,缩小攻击面,避免把env、heapdump等敏感端点暴露到公网。
采集配置:Categraf Prometheus 插件
Nightingale 的指标采集由 Categraf 完成。新建 conf/input.prometheus/springboot.toml:
[[instances]]
urls = ["http://127.0.0.1:8080/actuator/prometheus"]
url_label_key = "instance"
url_label_value = "{{.Host}}"
labels = { job = "springboot", application = "order-service" }
各字段的作用:
| 字段 | 示例值 | 说明 |
|---|---|---|
urls |
http://127.0.0.1:8080/actuator/prometheus |
要抓取的指标端点,可配置多个;每台被监控的 Spring Boot 实例一个 URL |
url_label_key |
instance |
抓取时给指标附加的标签键名 |
url_label_value |
{{.Host}} |
标签值模板,{{.Host}} 会被替换为该抓取目标的主机标识,用于区分不同实例 |
labels |
{ job = "springboot", application = "order-service" } |
静态附加标签,job 标识采集任务,application 标识业务应用名 |
从仓库自带的仪表盘(integrations/SpringBoot/dashboards/JVM(Actuator)withapplicationname.jsonwithapplicationname.json))可以看到,其模板变量通过 label_values(jvm_memory_used_bytes, application) 与 label_values(jvm_memory_used_bytes{application="$application"}, instance) 从真实数据中动态取 application 和 instance 的值。因此:
- 多实例部署时,同一应用的
application标签要保持一致(便于仪表盘按应用聚合筛选); - 每个实例的
instance标签必须唯一(用于区分同一应用的不同副本,便于按实例下钻排障)。
数据验证:先产生真实流量再下结论
JVM 的内存、GC、线程、HTTP 请求等指标中,很多是"事件驱动"或"按需初始化"的。只有产生真实 HTTP 请求、线程活动和 GC 之后,对应的速率(Rate)与延迟(Duration)面板才会出现数据。若仪表盘某面板长时间为空,先确认:
- 应用是否真的被请求过(压测、线上流量均可);
- JVM 是否发生过 GC(刚启动且堆未满时 GC 计数指标可能长时间为 0);
- 抓取端
curl http://127.0.0.1:8080/actuator/prometheus能否返回对应指标名。
验证通过后再导入仪表盘,避免误判为配置问题。
导入现成的 JVM 仪表盘
仓库在 integrations/SpringBoot/dashboards/ 提供两张仪表盘:
JVM.json:通用 JVM 仪表盘;JVM(Actuator)withapplicationname.json:按应用名(application)维度组织的 Actuator 专用仪表盘,与上文采集配置中的application标签配合使用。
以 JVM(Actuator)withapplicationname.json 为例,它包含以下分组(面板组):
| 分组 | 关键面板与指标 |
|---|---|
| Quick Facts | Start time(process_start_time_seconds)、Heap used / Non-Heap used(jvm_memory_used_bytes 占比)、Uptime(process_uptime_seconds) |
| I/O Overview | Rate(rate(http_server_requests_seconds_count[5m]))、Errors(5xx 速率)、Duration(平均/最大请求耗时)、Utilisation(Tomcat/Jetty 线程忙闲与上限) |
| JVM Memory | JVM Heap / Non-Heap / Total(jvm_memory_{used,committed,max}_bytes)、JVM Native Memory(process_memory_* 与 committed 差值) |
| JVM Misc | CPU(system_cpu_usage / process_cpu_usage)、File Descriptors、Threads(jvm_threads_*)、Thread States、Log Events(increase(logback_events_total[5m])) |
| JVM Memory Pools | 按 jvm_memory_pool_heap / jvm_memory_pool_nonheap 变量重复渲染的堆内/堆外各内存池面板 |
| Garbage Collection | Collections(rate(jvm_gc_pause_seconds_count[5m]))、Pause Durations(平均/最大停顿)、Allocated/Promoted |
| Classloading | Classes loaded、Class delta(5m 增量,用于观察类加载器是否泄漏) |
| Buffer Pools | Direct / Mapped 缓冲区的 used、capacity、count |
仪表盘自带 5 个模板变量:datasource(Prometheus 数据源)、application、instance、jvm_memory_pool_heap、jvm_memory_pool_nonheap,导入后在 Nightingale 中选择对应 Prometheus 数据源与目标应用即可使用。
提示:同类 JVM 仪表盘在 integrations/Java/markdown/README.md 中有区分说明——本仓库的 Java 集成里,JMX Exporter 与 OpenTelemetry Java Agent 的指标命名与 Actuator 不同(例如
jvm_gc_collection_seconds_*vsjvm_gc_pause_seconds_*),请选择与采集链路对应的仪表盘,不能混用。
现成的告警规则:从 PromQL 到处置建议
仓库在 integrations/SpringBoot/alerts/alerts.json 内置了 5 条 Prometheus 告警规则,可在 Nightingale 中直接导入,每条规则都带 annotations.action 处置建议。告警英文文案见 integrations/SpringBoot/i18n/en_US.json。
| 告警名称 | PromQL 要点 | 触发条件 | 内置处置建议摘要 |
|---|---|---|---|
| SpringBoot heap memory usage above 85% | sum by (instance)(jvm_memory_used_bytes{area="heap"}) * 100 / sum by (instance)(jvm_memory_max_bytes{area="heap"}) > 85 |
堆使用率超过 85% | 看 jvm_gc_pause_seconds 确认 Full GC 频率;用 jmap -histo:live 或 arthas heapdump 找异常增长类;区分业务量增长(调大 -Xmx)与内存泄漏(必须代码修复);应急重启前先抓堆快照 |
| SpringBoot non-heap memory usage above 85% | sum by (instance)(jvm_memory_max_bytes{area="nonheap"}) > 0 and ... * 100 / ... > 85 |
非堆使用率超过 85%(需 max > 0 避免除零) | 用 jcmd <pid> VM.native_memory summary 或 arthas memory 看各区占用;Metaspace 持续增长多为类加载器泄漏(热部署、动态代理、脚本引擎);应急调大 -XX:MaxMetaspaceSize;用 jmap -clstats 排查 ClassLoader |
| SpringBoot HTTP request latency exceeds 10s | max by (instance, uri)(http_server_requests_seconds_max{status!~"5.."}) > 10 |
非 5xx 请求最大耗时超 10 秒 | 从 uri 定位接口;用 arthas trace 或 APM 看耗时分布(DB/RPC/本地计算);慢查询补索引、下游加熔断降级;检查线程池是否被慢请求占满 |
| SpringBoot HTTP errors | sum by (instance, uri)(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) > 0 |
5 分钟窗口内出现 5xx 请求 | 从 uri 定位接口并搜异常栈;区分全量失败与部分失败;与发布时间吻合则优先回滚;确认数据库、缓存、第三方依赖是否同时异常 |
| SpringBoot event errors | sum by (instance)(increase(logback_events_total{level="error"}[5m])) > 0 |
5 分钟内产生 ERROR 日志 | 从 instance 定位实例,按 level=ERROR 检索时间窗堆栈;区分偶发(下游抖动、超时重试)与稳定复现(代码 bug);ERROR 突增且伴随发布则优先回滚 |
规则中的 prom_eval_interval 为 30 秒、prom_for_duration 为 60 秒(持续 1 分钟才告警),notify_recovered 开启恢复通知,notify_repeat_step 为 60 分钟重复提醒一次,可按团队值班习惯调整。
完整接入流程回顾
- 在 Spring Boot 应用加入 Actuator 与 Prometheus registry 依赖,按版本(2.x/3.x)写好暴露配置,
curl验证/actuator/prometheus; - 在 Categraf 新建
conf/input.prometheus/springboot.toml,配置urls与labels,保证application一致、instance唯一; - 产生真实流量与 GC 活动,确认速率、延迟面板有数据;
- 导入 JVM(Actuator)withapplicationname.jsonwithapplicationname.json) 仪表盘,按
application/instance筛选查看; - 导入 alerts.json 的五条告警规则,结合内置处置建议建立排障 SOP。
如此,一个从"指标暴露 → 采集 → 展示 → 告警 → 处置"的 Spring Boot 全链路可观测方案就完整落地了。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python670
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#230
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52874
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351