Micrometer 核心 API 的详细解析

Micrometer 的核心 API 是其强大监控能力的基础。它提供了一套简洁、统一且可扩展的接口,用于在 Java 应用中创建和管理度量指标(Metrics),并支持将这些指标导出到多种监控系统(如 Prometheus、InfluxDB、Datadog 等)。

下面是对 Micrometer 核心 API 的详细解析,涵盖主要接口、构建器模式、常用方法和使用方式。


一、核心 API 概览

Micrometer 的核心 API 主要围绕以下几个关键类和接口展开:

类/接口作用
MeterRegistry核心注册表,用于创建和管理所有 Meter
Meter所有指标的基类,表示一个具体的度量
Meter.Builder构建 Meter 的通用构建器(泛型)
Counter, Timer, Gauge, DistributionSummary, LongTaskTimer具体的 Meter 类型
Tag为指标添加维度标签
Timer.Sample用于手动测量耗时
MeterFilter控制度量注册行为
MeterBinder封装一组指标的绑定逻辑

二、MeterRegistry(度量注册表)——核心入口

MeterRegistry 是 Micrometer 的中央管理器,负责:

  • 创建各种类型的 Meter
  • 维护已注册的 Meter
  • 将指标数据导出到后端监控系统

常用方法

public class Example {
    private final MeterRegistry registry;

    public Example(MeterRegistry registry) {
        this.registry = registry;
    }

    public void demo() {
        // 1. 直接创建 Counter
        Counter counter = registry.counter("requests", "method", "GET");

        // 2. 使用 builder 创建更复杂的 Meter
        Timer timer = Timer.builder("http.request.duration")
            .tag("uri", "/api/users")
            .description("HTTP 请求耗时统计")
            .register(registry);

        // 3. 获取已存在的 Meter
        Counter existingCounter = registry.find("requests").tag("method", "GET").counter();

        // 4. 添加通用标签(推荐通过配置或 MeterFilter 设置)
        registry.config().commonTags("app", "user-service", "region", "us-east-1");
    }
}

💡 在 Spring Boot 中,MeterRegistry 会自动注入,开发者无需手动创建。


三、Meter.Builder —— 构建器模式

所有 Meter 都通过 Builder 模式创建,保证 API 一致性和可扩展性。

通用构建方法(适用于所有 Meter)

Meter.Builder<T> builder = Meter.builder(name, type, baseUnit)
    .tag(String key, String value)           // 添加标签
    .tags("k1", "v1", "k2", "v2")           // 批量添加标签
    .description("This is a custom metric") // 描述(可选)
    .register(registry);                    // 注册到 registry
  • name:指标名称(推荐小写 + 点分隔,如 http.server.requests
  • typeMeter.Type,如 COUNTER, GAUGE, TIMER
  • baseUnit:基本单位(可选),如 "seconds", "bytes"(主要用于文档和后端提示)

四、具体 Meter 类型 API 详解

1. Counter(计数器)

记录事件发生的次数,单调递增。

API 方法
Counter counter = Counter.builder("login.attempts")
    .tag("result", "success")
    .register(registry);

counter.increment();           // +1
counter.increment(5);          // +5

⚠️ 不支持减少(Micrometer 不提供 decrement() 方法)


2. Gauge(仪表)

测量当前瞬时值,常用于资源状态监控。

API 方法
List<String> queue = new ArrayList<>();

// 方式一:通过函数回调创建
Gauge gauge = Gauge.builder("queue.size", queue, List::size)
    .register(registry);

// 方式二:手动设置(不推荐,容易出错)
Gauge.builder("memory.usage", () -> Runtime.getRuntime().freeMemory())
    .register(registry);

✅ 推荐使用 FunctionGauge,自动定期采样。


3. Timer(计时器)

记录操作执行时间,支持统计:count、total time、max、percentiles、histogram。

API 方法
Timer timer = Timer.builder("db.query.time")
    .tag("operation", "select")
    .publishPercentiles(0.5, 0.95, 0.99)  // 发布 50%, 95%, 99% 分位数
    .publishPercentileHistogram()         // 启用直方图(Prometheus 推荐)
    .register(registry);

// 记录一次调用
timer.record(Duration.ofMillis(123));

// 或直接执行并计时
timer.record(() -> {
    // 业务逻辑
});

// 手动控制开始/结束(更灵活)
Timer.Sample sample = timer.start();
try {
    // 执行操作
} finally {
    sample.stop();
}

⚠️ Timer.Sample 必须调用 stop(),否则会导致内存泄漏或统计错误。


4. DistributionSummary(分布摘要)

记录事件的大小分布(非时间),如请求体大小、响应字节数。

API 方法
DistributionSummary summary = DistributionSummary.builder("request.size.bytes")
    .baseUnit("bytes")
    .publishPercentiles(0.5, 0.9, 0.99)
    .minimumExpectedValue(1L)
    .maximumExpectedValue(1024 * 1024L) // 1MB
    .register(registry);

summary.record(512);  // 记录一个值

📌 与 Timer 类似,但不关心时间单位。


5. LongTaskTimer(长任务计时器)

用于测量长时间运行的任务(如批处理、异步任务)。

API 方法
LongTaskTimer timer = LongTaskTimer.builder("batch.job.duration")
    .register(registry);

// 开始任务
LongTaskTimer.Sample sample = timer.start();

// 模拟任务执行
Thread.sleep(5000);

// 结束任务
sample.stop();

导出的指标包括:

  • batch_job_duration_seconds_active:当前正在运行的任务数
  • batch_job_duration_seconds_duration:已完成任务的总耗时

6. FunctionCounter / FunctionTimer / FunctionGauge

基于现有对象自动暴露指标,无需手动更新。

FunctionCounter 示例
AtomicLong processedMessages = new AtomicLong();

FunctionCounter.builder("messages.processed", processedMessages, AtomicLong::get)
    .baseUnit("messages")
    .register(registry);
FunctionTimer 示例
MessageProcessor processor = ...;

FunctionTimer.builder("message.processing.time", processor,
    p -> p.getCount(),           // total count
    p -> p.getTotalTimeNanos(),  // total time in nanos
    TimeUnit.NANOSECONDS)
.register(registry);

✅ 这些是“拉模型”指标的最佳实践,性能好且线程安全。


五、Tag(标签)API

标签是 Micrometer 实现多维监控的核心。

创建标签

Tag tag = Tag.of("status", "200");
Iterable<Tag> tags = Tags.of("method", "GET", "uri", "/api/users");

registry.counter("http.requests", tags);

使用 io.micrometer.core.instrument.util.Tags

import static io.micrometer.core.instrument.util.Tags.*;

Tags.of("method", "GET").and("status", "200");

✅ 建议:使用常量或枚举管理标签键,避免拼写错误。


六、MeterFilter(度量过滤器)

用于全局控制 Meter 的注册行为。

常见用法

@Bean
public MeterFilter commonTags() {
    return MeterFilter.commonTags(Arrays.asList(
        Tag.of("service", "order-service"),
        Tag.of("env", "prod")
    ));
}

@Bean
public MeterFilter denyJmx() {
    return MeterFilter.deny(id -> id.getName().startsWith("jvm."));
}

@Bean
public MeterFilter renameHttp() {
    return MeterFilter.rename("old.name", "new.name");
}

✅ 多个 MeterFilter 可以链式组合,顺序很重要。


七、MeterBinder(度量绑定器)

将一组相关指标封装成可复用组件。

@Component
public class ThreadPoolMetrics implements MeterBinder {

    private final ExecutorService executor = Executors.newFixedThreadPool(10);

    @Override
    public void bindTo(MeterRegistry registry) {
        Gauge.builder("thread.pool.active", executor, 
            exec -> ((ThreadPoolExecutor) exec).getActiveCount())
            .register(registry);

        Gauge.builder("thread.pool.queue.size", executor,
            exec -> ((ThreadPoolExecutor) exec).getQueue().size())
            .register(registry);
    }
}

✅ Spring Boot 会自动调用所有 MeterBinder bean 的 bindTo() 方法。


八、高级 API:Clock 与 StepMeterRegistry

1. Clock 接口

控制时间源,用于测试或特殊时钟同步。

Clock.SYSTEM  // 默认系统时钟
Clock.WALL    // 墙钟时间

2. StepMeterRegistry

用于定时推送指标的后端(如 Graphite、InfluxDB),定期将数据批量发送。

  • 包含 step(推送间隔,如 1 分钟)
  • 子类如 GraphiteMeterRegistry, InfluxMeterRegistry

九、API 设计哲学总结

特性说明
统一构建器模式所有 Meter 使用 .builder().register() 模式
不可变配置Builder 创建后不可变,线程安全
拉模型优先推荐 FunctionGauge 而非手动 Gauge
标签驱动所有指标支持多维分析
非侵入式不依赖具体监控后端
自动配置友好与 Spring Boot Actuator 深度集成

十、最佳实践建议

  1. 使用 builder 模式创建 Meter,避免直接调用 registry 的快捷方法(便于扩展)。
  2. 合理命名指标:小写、点分隔、语义清晰(如 http.client.requests)。
  3. 避免高基数标签:不要用用户 ID、IP 地址等作为标签。
  4. 启用 Percentile Histogram:对 Prometheus 用户尤其重要。
  5. 优先使用自动指标:Spring Boot 已提供大量 JVM、HTTP、Cache 等指标。
  6. 自定义指标要有业务价值:如订单创建数、支付成功率等。

参考文档


掌握 Micrometer 的核心 API,不仅能帮助你准确采集应用指标,还能提升系统的可观测性(Observability),为性能调优、故障排查和容量规划提供数据支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值