Prometheus 监控 Spring Boot 实战宝典:Micrometer 打通应用层可观测性的最后一公里
在微服务体系里,Spring Boot 应用是核心业务承载体,它的健康状态、吞吐量、JVM 内存、数据库连接池、自定义业务指标等,必须纳入统一监控。Prometheus 生态借助Micrometer提供了完美的桥接——只需引入一个依赖,就能将 Actuator 指标暴露为 Prometheus 格式。本文将带你从零集成,到掌握 JVM/HTTP/业务指标、搭建 Dashboard、配置告警,构建完整的应用层可观测性。
1. 为什么选 Micrometer + Prometheus?
- 厂商无关的指标门面:Micrometer 是 Spring Boot 2/3 默认的指标库,支持对接 Prometheus、Datadog、OTel 等多种后端。
- 开箱即用的 JVM 与中间件指标:内存、GC、线程、Tomcat、数据库连接池、RabbitMQ 等自动采集。
- 自定义业务指标极其简单:几行代码就能定义 Counter、Gauge、Timer。
- 无缝集成 Prometheus:暴露
/actuator/prometheus端点,原生直连抓取。
2. 快速集成
2.1 添加依赖
Maven:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId><version>1.12.2</version><!-- 根据 Spring Boot 版本匹配 --></dependency>Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus'Spring Boot 2.x 和 3.x 均可使用,3.x 默认使用 Micrometer 1.11+ 并内置了 Prometheus 注册表(但有时仍需显式添加依赖)。
2.2 配置暴露端点
在application.yml(或 properties)中:
management:endpoints:web:exposure:include:health,info,prometheus,metricsendpoint:prometheus:enabled:truemetrics:export:prometheus:enabled:truetags:application:${spring.application.name}# 为所有指标打上应用名标签启动应用后,访问http://localhost:8080/actuator/prometheus即可看到大量指标输出。
2.3 安全控制
生产环境不应公开暴露所有端点,建议:
management:server:port:8081# 单独管理端口,避免与外网端口混淆endpoints:web:exposure:include:prometheus# 仅暴露 prometheus 端点base-path:/actuator结合 Spring Security 可添加基本认证,或在防火墙层面只允许 Prometheus 服务器 IP 访问管理端口。
3. Prometheus 抓取配置
scrape_configs:-job_name:'spring-boot-app'metrics_path:'/actuator/prometheus'scrape_interval:15sstatic_configs:-targets:-'10.0.0.50:8081'# 管理端口labels:app:'order-service'env:'production'如果有多个实例,可使用文件发现或 K8s 服务发现。
4. 核心指标解读
Micrometer 自动暴露了大量指标,分为 JVM 指标、系统指标、应用指标。
| 分类 | 指标名示例 | 含义 | PromQL 示例 |
|---|---|---|---|
| JVM 内存 | jvm_memory_used_bytesjvm_memory_max_bytes | 堆/非堆使用量及最大值 | jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} |
| JVM GC | jvm_gc_pause_seconds_countjvm_gc_pause_seconds_sum | GC 次数与累计暂停时间 | rate(jvm_gc_pause_seconds_sum[1m]) / rate(jvm_gc_pause_seconds_count[1m])得平均暂停时间 |
| JVM 线程 | jvm_threads_live_threads | 当前活跃线程数 | 结合峰值jvm_threads_peak_threads分析 |
| CPU | process_cpu_usage | 进程 CPU 使用率 (0~1) | process_cpu_usage * 100 |
| HTTP 请求 | http_server_requests_seconds_counthttp_server_requests_seconds_sum | 请求总数与总耗时 | QPS:rate(http_server_requests_seconds_count[1m])平均延迟: rate(http_server_requests_seconds_sum[1m]) / rate(http_server_requests_seconds_count[1m]) |
| HTTP 状态码 | http_server_requests_seconds_bucket带 status标签 | 可按 status 分类统计 | sum(rate(http_server_requests_seconds_count{status=~"5.."}[1m]))得 5xx 速率 |
| Tomcat 连接 | tomcat_threads_busy_threadstomcat_threads_config_max_threads | Tomcat 忙碌线程数与最大线程数 | tomcat_threads_busy_threads / tomcat_threads_config_max_threads |
| 数据源连接池 | hikaricp_connections_activehikaricp_connections_idlehikaricp_connections_pending | 活跃/空闲/等待获取的连接数 | 等待连接数hikaricp_connections_pending > 0需关注 |
| 日志事件 | logback_events_total(若集成) | 按级别统计日志条数 | rate(logback_events_total{level="error"}[1m])错误日志速率 |
注意:指标名和标签取决于 Spring Boot 版本和依赖。例如
http_server_requests_seconds在 2.x 中可能为http_server_requests_seconds,3.x 一致。数据库连接池默认使用 HikariCP,其指标前缀为hikaricp_*。
5. 自定义业务指标
5.1 使用 MeterRegistry 定义
importio.micrometer.core.instrument.*;@ServicepublicclassOrderService{privatefinalCounterordersTotal;privatefinalTimerorderProcessingTimer;publicOrderService(MeterRegistryregistry){ordersTotal=Counter.builder("orders.total").description("Total orders created").register(registry);orderProcessingTimer=Timer.builder("orders.processing.time").description("Order processing duration").register(registry);}publicvoidcreateOrder(Orderorder){longstart=System.currentTimeMillis();// ... 业务逻辑ordersTotal.increment();orderProcessingTimer.record(System.currentTimeMillis()-start,TimeUnit.MILLISECONDS);}}5.2 用@Timed注解(需要 AOP)
添加依赖spring-boot-starter-aop,然后在配置类上启用@Timed:
@Configuration@EnableAspectJAutoProxypublicclassTimedConfiguration{@BeanpublicTimedAspecttimedAspect(MeterRegistryregistry){returnnewTimedAspect(registry);}}在方法上使用:
@Timed(value="orders.find.latency",extraTags={"type","search"})publicList<Order>findOrders(){...}5.3 Gauge 动态指标
AtomicIntegerqueueSize=newAtomicInteger();registry.gauge("custom.queue.size",queueSize);// 当 queueSize 变化时,指标自动更新这些自定义指标会和系统指标一起暴露在/actuator/prometheus,Prometheus 抓取后可直接查询。
6. Grafana 仪表盘推荐
直接导入以下社区仪表盘(均适配 Micrometer):
- Spring Boot 2.x / 3.x 通用大屏:Dashboard ID10254(Spring Boot Micrometer)
包含 JVM 概览、HTTP 请求统计、Tomcat 连接、HikariCP 池、日志统计等,功能全面。 - JVM 监控专用 (Micrometer):Dashboard ID4701(JVM (Micrometer))
偏重 JVM 内存、GC、线程分析。 - Spring Boot 指标概览:Dashboard ID12900(Spring Boot 2.x & 3.x)
简洁现代风格,聚焦应用健康。
导入时选择 Prometheus 数据源,并将application变量设置为你的应用标签即可。
7. 告警规则实战
groups:-name:springboot_alertsrules:-alert:SpringBootDownexpr:up{job="spring-boot-app"}== 0for:1mlabels:severity:criticalannotations:summary:"应用 {{ $labels.app }} 实例 {{ $labels.instance }} 宕机"-alert:High5xxRateexpr:sum(rate(http_server_requests_seconds_count{status=~"5..",job="spring-boot-app"}[5m])) by (app) / sum(rate(http_server_requests_seconds_count{job="spring-boot-app"}[5m])) by (app)>0.01for:2mlabels:severity:criticalannotations:summary:"{{ $labels.app }} 的 5xx 错误率超过 1%"-alert:HighAvgResponseTimeexpr:rate(http_server_requests_seconds_sum[5m]) / rate(http_server_requests_seconds_count[5m])>1for:5mlabels:severity:warningannotations:summary:"{{ $labels.app }} 平均响应时间超过 1 秒"-alert:JvmMemoryHighexpr:(jvm_memory_used_bytes{area="heap"}/ jvm_memory_max_bytes{area="heap"})>0.9for:5mlabels:severity:warningannotations:summary:"{{ $labels.app }} 堆内存使用率超过 90%"-alert:GcPauseTooFrequentexpr:rate(jvm_gc_pause_seconds_count[10m])>5for:5mlabels:severity:warningannotations:summary:"{{ $labels.app }} GC 频率过高 (>5次/分钟)"-alert:TomcatThreadsNearMaxexpr:tomcat_threads_busy_threads / tomcat_threads_config_max_threads>0.8for:2mlabels:severity:criticalannotations:summary:"{{ $labels.app }} Tomcat 忙碌线程超过 80%,即将拒绝请求"-alert:HikariPoolConnectionPendingexpr:hikaricp_connections_pending>0for:1mlabels:severity:warningannotations:summary:"{{ $labels.app }} 数据库连接池出现等待"可根据实际指标名称微调(例如 Spring Boot 3 中http_server_requests_seconds_count前缀确定,老版本可能是http_server_requests_seconds_count,但基本一致)。
8. 进阶配置与最佳实践
8.1 过滤和定制指标
通过配置文件可以过滤掉不想暴露的指标,减小体积:
management:metrics:enable:jvm:truelogback:truetomcat:truehikaricp:truedistribution:percentiles-histogram:http.server.requests:true# 开启直方图,便于计算 P95/P99slo:http.server.requests:100ms,200ms,500ms,1s8.2 Spring Security 保护 Prometheus 端点
@BeanpublicSecurityFilterChainactuatorSecurityFilterChain(HttpSecurityhttp)throwsException{http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(auth->auth.requestMatchers(EndpointRequest.to("prometheus")).hasRole("MONITOR").anyRequest().authenticated()).httpBasic(Customizer.withDefaults());returnhttp.build();}Prometheus 侧需配置basic_auth:
scrape_configs:-job_name:'secure-springboot'metrics_path:'/actuator/prometheus'basic_auth:username:monitor_userpassword:strong_passwordstatic_configs:-targets:['app:8081']8.3 Kubernetes 环境
在 K8s 中部署 Spring Boot 应用,无需硬编码 target,可利用 Prometheus Operator 的PodMonitor或注解自动发现:
apiVersion:monitoring.coreos.com/v1kind:PodMonitormetadata:name:spring-boot-appspec:selector:matchLabels:app:order-servicepodMetricsEndpoints:-port:management# 管理端口名称path:/actuator/prometheus8.4 分布式链路追踪联动
结合Micrometer Tracing+OpenTelemetry可将指标与 trace 关联,Prometheus 侧虽无法直接展示 trace,但可通过 Grafana + Tempo/Jaeger 实现关联。
9. 安全与性能注意事项
- 指标端点不宜公网暴露:始终使用独立管理端口或内部网络访问。
- 高基数标签 (High Cardinality)是大忌:避免将请求 URI 含参数等作为标签,默认 Spring Boot 只保留 URI 模式 (如
/users/{id}),如果自定义 Tag,务必控制变量。 - 抓取频率:15s~30s 足够,频繁抓取会增加应用内存消耗(Micrometer 内存中维持所有指标状态)。
- 升级版本:Spring Boot 3.x 和 Micrometer 1.11+ 在性能和内存上有优化,推荐使用最新稳定版。
将这套方案落地后,你的 Spring Boot 应用就从“黑盒”变成一个完全透明、指标驱动的可观测系统。无论是内存泄漏、接口延迟抖动、数据库连接池耗尽,还是业务异常激增,都能在 Grafana 上直观呈现,并由 Prometheus Alertmanager 第一时间通知你。它不仅是运维者的利器,更是开发人员优化性能的数据源泉。