导读:本期聚焦于韩兆瑞创作的《Spring Boot 如何通过 Micrometer 对接 Prometheus 实现指标监控?》,敬请观看详情。Spring Boot 应用自带了大量运行时指标,但默认数据只是躺在 Actuator 端点里,没有可视化和告警能力。本文介绍如何利用 Micrometer 这个指标门面库,把 Spring Boot 内置指标以及自定义业务指标以 Prometheus 认识的格式暴露出来,再交给 Prometheus 抓取和 Grafana 展示。内容涵盖依赖引入、配置调整、常用计量器类型、业务埋点写法、Prometheus 抓取配置以及常见问题排查,帮你快速搭建一套可落地的应用监控体系。

Spring Boot 从 2.0 开始就把底层指标系统换成了 Micrometer,它相当于指标界的 SLF4J,屏蔽了不同监控后端的差异。只要在代码里用统一的 API 记录指标,换监控后端时几乎不用改业务代码。而 Prometheus 作为当下最主流的开源监控系统,配合 Grafana 可以轻松实现指标可视化。把两者打通,是搭建应用监控体系最常见的一条路径。

Spring Boot 如何通过 Micrometer 对接 Prometheus 实现指标监控?

一、理解 Micrometer 与 Prometheus 的关系

很多刚接触监控的同学容易把 Micrometer 和 Prometheus 混为一谈,这里先厘清概念。Micrometer 是一个指标门面库,运行在应用程序内部,负责定义和收集指标;Prometheus 是一个独立的时序数据库和监控系统,负责从应用拉取数据、存储和查询。两者之间通过 Prometheus 特有的文本暴露格式通信。

具体来说,当你在 Spring Boot 里调用 MeterRegistry.counter("order.created") 时,Micrometer 会在内存里维护这个计数器的状态。当你引入了 micrometer-registry-prometheus 依赖后,Micrometer 会提供一个 PrometheusMeterRegistry,它把所有指标渲染成 Prometheus 可解析的文本格式。Actuator 的 /actuator/prometheus 端点访问时返回的就是这份文本,Prometheus 服务端定时抓取这个端点,数据就进了时序库。

这套机制的好处是解耦:如果哪天公司换成了 InfluxDB 或者 Datadog,你只需要换依赖和注册器实现,业务代码里的埋点一行都不用动。这也是推荐通过 Micrometer 间接对接而不是直接写 Prometheus 客户端 SDK 的主要原因。

二、引入依赖并完成基础配置

第一步是添加 Prometheus 注册器依赖。如果项目已经引入了 spring-boot-starter-actuator,只需要再加一个依赖即可:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

接下来在配置文件中暴露端点。Spring Boot 2.x 用 properties 或 yml 均可,下面以 yml 为例:

management:
  endpoints:
    web:
      exposure:
        include: health,prometheus
  metrics:
    tags:
      application: ${spring.application.name}
    export:
      prometheus:
        enabled: true

这里有一个很关键的配置:management.metrics.tags.application。它会给所有指标打上一个应用名标签,在多服务共用一个 Prometheus 的场景下,没有这个标签你几乎无法区分数据来自哪个服务,建议务必加上。配置完成后启动应用,访问 http://127.0.0.1:8080/actuator/prometheus,能看到类似下面的文本输出就说明成功了:

# HELP jvm_memory_used_bytes ...
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="PS Eden Space",application="order-service",} 4.3E7

三、在业务代码中记录自定义指标

内置指标只能反映 JVM、HTTP 请求等通用信息,监控的核心价值往往在业务指标上。Micrometer 提供了几种常用的计量器类型,选择合适的类型很重要:

  • Counter(计数器):只增不减的量,比如订单创建次数、异常发生次数。
  • Gauge(瞬时值):某个时刻的值,比如当前队列长度、缓存条目数。
  • Timer(耗时):记录事件耗时和次数,适合接口或任务执行时长统计。
  • DistributionSummary(分布):记录事件的值分布,比如一次请求传输的字节数。

下面是一个典型的订单服务埋点示例,通过构造器注入 MeterRegistry,在业务方法中同时记录下单次数和处理耗时:

@Service
public class OrderService {

    private final Counter orderCounter;
    private final Timer orderTimer;

    public OrderService(MeterRegistry registry) {
        this.orderCounter = Counter.builder("order.created.total")
                .description("订单创建总数")
                .tag("channel", "app")
                .register(registry);
        this.orderTimer = Timer.builder("order.process.duration")
                .description("订单处理耗时")
                .publishPercentileHistogram()
                .register(registry);
    }

    public void createOrder(OrderRequest request) {
        orderTimer.record(() -> {
            // 实际下单逻辑
            doCreate(request);
            orderCounter.increment();
        });
    }
}

有几个实践上的注意点。第一,指标命名建议用小写加英文句点的风格,Micrometer 会自动把它转成 Prometheus 的下划线格式,order.created.total 最终会变成 order_created_total。第二,标签的取值要控制在有限集合内,千万不要把用户 ID、订单号这类高基数值放进标签,否则指标维度爆炸会直接拖垮 Prometheus。第三,Timer 加上 publishPercentileHistogram() 后可以配合 Prometheus 的 histogram_quantile 函数计算 P95、P99 分位耗时,对性能分析非常有用。

还有一种常见需求是对既有对象做 Gauge 监控,比如监控某个内存队列的长度。可以借助强引用持有被监控对象,避免 Gauge 指向的对象被垃圾回收后一直返回 NaN:

@Service
public class QueueMonitor {

    private final LinkedBlockingQueue<Task> queue = new LinkedBlockingQueue<>(1000);

    @PostConstruct
    public void init() {
        // 使用强引用持有 list,防止被 GC 后 gauge 失效
        List<LinkedBlockingQueue<Task>> holder = new ArrayList<>();
        holder.add(queue);
        Gauge.builder("task.queue.size", holder, Collection::size)
             .description("待处理任务队列长度")
             .register(registry);
    }
}

四、配置 Prometheus 抓取与验证

应用侧准备就绪后,需要让 Prometheus 知道去哪里抓数据。修改 Prometheus 的配置文件 prometheus.yml,添加一个抓取任务:

scrape_configs:
  - job_name: 'order-service'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    static_configs:
      - targets: ['192.168.0.10:8080']
        labels:
          env: 'prod'

服务实例少的时候静态配置够用,但如果部署在 Kubernetes 上,更推荐使用服务发现,把 pod 的所有者信息自动作为标签,避免每次扩容都手动改配置。配置重载后访问 Prometheus 自带的 Web 界面,在 Status 菜单的 Targets 页面能看到目标处于 UP 状态即表示抓取正常。

随后可以试着查询一下,比如统计每分钟的订单创建速率:rate(order_created_total[1m]),这比直接看计数器的累计值有意义得多。Grafana 接入 Prometheus 数据源后,可以把这类查询语句直接做成面板,配合官方社区发布的 Spring Boot 监控仪表盘模板,JVM 内存、GC、线程、HTTP 请求等常见图表基本可以开箱即用。

五、常见问题排查思路

实际落地时难免踩坑,这里总结几个高频问题。一是端点访问返回 404,多半是 management.endpoints.web.exposure.include 没有包含 prometheus,或者项目里存在自定义的安全拦截器把 Actuator 路径拦掉了,需要放行该路径。二是 Prometheus 页面上目标一直显示 DOWN,先确认网络连通性,再用 curl 直接请求应用的端点看返回内容,同时注意抓取超时时间要小于抓取间隔。

三是指标数据出现断点或丢失。Prometheus 是拉取模型,应用重启会导致计数器归零,这在 Prometheus 端是正常现象,查询时配合 rate()increase() 函数可以正确处理计数器重置。另外要检查指标基数,可以用 count by (__name__)({__name__=~".+"}) 之类的查询定位哪个指标维度异常膨胀,及时清理不合理的标签。

四是 Spring Boot 3.x 用户的依赖坐标有变化,Actuator 相关模块迁移到了新的命名空间,引入依赖时注意groupId要写 org.springframework.boot 对应的新版本,同时确认 Micrometer 版本与 Boot 版本匹配,一般由 Boot 的依赖管理自动对齐,不需要手动指定版本号。

整体来看,Micrometer 加 Prometheus 的组合配置成本不高,却能让应用从黑盒变成白盒。建议先从内置指标接入做起,再逐步补充业务埋点,让监控数据真正参与到日常的容量评估和故障定位中去。

MicrometerSpring BootPrometheus修改时间:2026-09-06 04:10:41

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260906/51329.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。