Micrometer 是 Java 应用中用于收集应用程序度量指标的核心库,它作为一项监控门面(Facade) 技术,可以与各种监控系统集成,帮助你收集和分析应用性能数据。下面这张表格汇总了 Micrometer 的核心概念,方便你快速建立整体印象。
| 概念维度 | 核心要点 | 说明与价值 |
|---|---|---|
| 统一抽象 | 供应商中立 (Vendor-neutral) | 提供一套通用 API,使应用代码与具体监控系统(如 Prometheus, Datadog)解耦。 |
| 核心模型 | Meter (度量器) 与 MeterRegistry(注册中心) | Meter 用于收集特定指标(如计数器、计时器)。MeterRegistry 负责创建和管理 Meter,并将数据发布到监控系统。 |
| 维度化数据 | Tags(标签) | 为度量指标添加键值对标签(如 uri=/api/users, status=200),实现高性能、多维度数据查询与钻取。 |
| 丰富度量类型 | Counter (计数器), Timer (计时器), Gauge (仪表), DistributionSummary(分布摘要) 等 | 支持不同场景的度量需求,如计数、耗时、瞬时值、数据分布统计等。 |
🔌 快速集成与配置
Spring Boot 为 Micrometer 提供了强大的自动配置支持。
-
添加依赖
核心依赖是
spring-boot-starter-actuator,它内置了 Micrometer。你还需要引入对应监控系统(以 Prometheus 为例)的依赖。xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- 以 Prometheus 为例 --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> -
基础配置
在
application.yml中进行配置,暴露端点并设置通用标签。yamlmanagement: endpoints: web: exposure: include: health,info,metrics,prometheus # 暴露所需端点,包括prometheus metrics: tags: application: ${spring.application.name} # 设置通用标签,标识应用 export: prometheus: enabled: true配置后,可通过
/actuator/prometheus访问指标。 -
使用全局标签
使用
MeterRegistryCustomizer配置全局标签,这些标签会附加到所有指标上。kotlin@Configuration public class MetricsConfig { @Bean public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() { return registry -> registry.config().commonTags("region", "us-east-1", "env", "prod"); } }
📊 使用度量指标
Micrometer 提供了多种度量器(Meter)类型,用于不同场景的指标收集。
-
Counter(计数器) :用于记录单调递增的数值,例如订单量、访问次数。它特别适用于报告某个事件发生的总次数,监控系统通常更关注其增长速率。
java@Service public class OrderService { private final Counter orderCounter; public OrderService(MeterRegistry registry) { // 创建计数器,建议使用点号分隔的命名方式,并添加有意义的标签 orderCounter = Counter.builder("order.created") .description("Number of orders created") .tag("channel", "WEB") // 使用低基数标签 .register(registry); } public void createOrder() { // 业务逻辑 orderCounter.increment(); // 下单成功后计数器+1 } } -
Gauge(仪表) :用于测量瞬时值,例如当前在线人数、队列大小。Gauge 测量的值是可增可减的,适用于观察那些有自然上限的指标。通常通过引用一个会变化的对象(如
AtomicInteger)来创建。arduino@Component public class CacheMetrics { private final List<String> cache = new ArrayList<>(); public CacheMetrics(MeterRegistry registry) { // 监控缓存大小 Gauge.builder("cache.size", cache, List::size) .description("Current size of the cache") .register(registry); } } -
Timer(计时器):用于记录短时任务的执行时间,并测量其频率,例如接口请求耗时。Timer 会记录事件的总次数(count)和总耗时(totalTime),从而可以计算平均耗时等数据。
java@Service public class ApiService { private final Timer apiTimer; public ApiService(MeterRegistry registry) { apiTimer = Timer.builder("api.call.duration") .description("Duration of API calls") .tags("api_name", "getUserInfo") .publishPercentiles(0.95, 0.99) // 发布95%和99%分位数 .register(registry); } public String callExternalApi() { // 方式一:使用Timer.Sample手动记录 Timer.Sample sample = Timer.start(registry); String result; try { result = // ... 调用外部API的逻辑 } finally { sample.stop(apiTimer); } return result; // 方式二:使用函数式接口(更简洁) // return apiTimer.record(() -> { ... }); } } -
使用
@Timed和@Counted注解Micrometer 提供注解,可以更方便地使用方法级别监控。
less@Configuration public class TimedConfiguration { // 启用@Timed注解支持 @Bean public TimedAspect timedAspect(MeterRegistry registry) { return new TimedAspect(registry); } } @Service public class BusinessService { @Timed(value = "order.process.time", description = "Order processing time") @Counted(value = "order.process.count", description = "Order processing count") public void processOrder() { // 业务逻辑 } }
⚙️ 生产环境最佳实践
-
避免标签基数爆炸 :不要使用高基数(高唯一性)的值作为标签,例如用户ID、订单ID,这会导致创建海量时间序列,给监控系统带来巨大压力。应使用像状态(
status)、接口路径(uri,建议模板化)、错误类型(error_type)这样的低基数标签。 -
配置百分比直方图:对于 Timer 和 DistributionSummary,可以在配置中启用百分比直方图,这有助于在服务端(如 Prometheus)进行更灵活的聚合查询。
yamlmanagement: metrics: distribution: percentiles: http.server.requests: 0.5, 0.95, 0.99 # 为HTTP请求配置分位数 percentile-histogram: http.server.requests: true # 启用直方图 -
使用 MeterFilter 进行控制 :
MeterFilter可以用来拒绝、修改或配置 Meter。例如,可以忽略某些标签,或为特定 Meter 设置统一的统计配置。typescript@Bean public MeterFilter meterFilter() { // 例如,忽略某个高基数标签,或者统一为所有Timer设置百分位 return MeterFilter.ignoreTags("high-cardinality-tag"); }
📈 与监控系统集成
Micrometer 收集的指标数据需要通过对应的 MeterRegistry实现发布到监控系统。以 Prometheus 为例,引入 micrometer-registry-prometheus依赖并配置暴露端点后,Prometheus 服务器可以定期从应用的 /actuator/prometheus端点拉取数据。随后,可以在 Grafana 中利用 PromQL 查询语言创建丰富的监控仪表盘。
💎 总结
Micrometer 的核心价值在于其统一的抽象层 ,使得应用监控代码与具体监控后端解耦。掌握其维度化数据模型(Tags) 和丰富的度量器类型(Meter Types) 是利用其强大能力的关键。