当前位置: 首页 > news >正文

【Springboot知识】Springboot进阶-Micrometer指标监控深入解析

文章目录

    • ​​Micrometer 核心概念与标准指标详解
      • **Micrometer 核心概念与标准指标详解**
        • **一、Micrometer 核心概念**
        • **二、Micrometer 标准指标**
          • **1. JVM 监控指标**
          • **2. 系统资源监控**
          • **3. HTTP 请求监控**
          • **4. 数据库监控**
          • **5. 缓存监控**
        • **三、配置与自定义指标**
          • **1. 启用/禁用特定指标**
          • **2. 添加自定义标签**
          • **3. 指标命名规则**
        • **四、监控数据展示示例(Prometheus)**
        • **五、总结**
    • springboot结合Micrometer
      • **Spring Boot 集成 Micrometer 实现指标监控**
        • **一、添加依赖**
        • **二、配置监控端点**
        • **三、自动采集的指标**
        • **四、自定义业务指标**
          • **1. 计数器(Counter)统计订单创建次数**
          • **2. 计时器(Timer)统计方法耗时**
          • **3. 仪表(Gauge)监控队列大小**
        • **五、高级配置**
          • **1. 全局标签(区分环境/区域)**
          • **2. 过滤不需要的指标**
          • **3. 自定义指标命名规则**
        • **六、验证与可视化**
        • **七、总结**
    • 自定义一个Micrometer
      • **一、自定义 MeterRegistry(监控数据上报)**
        • **1. 实现自定义注册中心**
        • **2. 注册自定义 Registry 到 Spring 上下文**
        • **3. 配置 `application.properties`**
      • **二、自定义指标采集逻辑**
        • **1. 创建自定义 Meter(例如统计缓存穿透次数)**
        • **2. 自定义 MeterFilter(过滤或修改指标)**
        • **3. 动态标签(基于请求上下文)**
      • **三、验证自定义效果**
      • **四、注意事项**
    • 关联知识

​​Micrometer 核心概念与标准指标详解

Micrometer 核心概念与标准指标详解

一、Micrometer 核心概念

Micrometer 是一款 监控指标门面库(类似 SLF4J 在日志领域的作用),为 Java 应用提供统一的监控指标采集接口,支持对接 Prometheus、Datadog、InfluxDB 等主流监控系统。以下是其核心组件:

概念说明
Meter指标的最小单元,表示一个可测量的值(如请求数、响应时间)。
MeterRegistry管理所有 Meter 的注册中心,负责将指标发布到监控后端(如 Prometheus)。
MeterProvider创建 Meter 的工厂,支持通过标签(Tags)动态生成指标。
Tags键值对标签,用于为指标添加维度(如 method=GET, status=200)。
Naming Convention指标命名规则(如 snake_casecamelCase),适配不同监控系统的要求。

二、Micrometer 标准指标

Micrometer 内置了多种 自动采集的指标,涵盖 JVM、系统资源、HTTP 请求等关键领域。


1. JVM 监控指标
指标名称类型说明
jvm.memory.usedGaugeJVM 内存使用量(单位:字节)
jvm.memory.committedGaugeJVM 已提交内存(包括未使用的预分配内存)
jvm.threads.liveGauge当前存活线程数
jvm.gc.pauseTimerGC 暂停时间统计(次数、总耗时、最大耗时)
jvm.classes.loadedGauge已加载的类数量

示例配置(自动启用):

management.metrics.enable.jvm=true

2. 系统资源监控
指标名称类型说明
system.cpu.usageGauge系统 CPU 使用率(0~1)
process.cpu.usageGauge当前进程 CPU 使用率
process.files.openGauge进程打开的文件句柄数
process.uptimeGauge进程运行时间(单位:秒)

示例配置:

management.metrics.enable.process=true
management.metrics.enable.system=true
3. HTTP 请求监控

Spring Boot 自动为 Web 应用(如 Spring MVC)生成 HTTP 指标:

指标名称类型说明
http.server.requestsTimerHTTP 请求耗时统计(次数、延迟、状态码等)
http.client.requestsTimerHTTP 客户端请求耗时(如 RestTemplate 调用)

标签示例:
method: HTTP 方法(GET/POST 等)
uri: 请求路径(如 /api/users
status: HTTP 状态码(200/404/500 等)

启用配置:

management.metrics.enable.http=true
4. 数据库监控

集成 HikariCP、Tomcat JDBC 等连接池时自动生成:

指标名称类型说明
jdbc.connections.activeGauge活跃数据库连接数
jdbc.connections.idleGauge空闲数据库连接数
jdbc.connections.maxGauge最大允许连接数

标签示例:
pool: 连接池名称(如 HikariPool-1

5. 缓存监控

支持 Caffeine、EhCache 等缓存框架:

指标名称类型说明
cache.getsCounter缓存查询次数(命中 + 未命中)
cache.hitsCounter缓存命中次数
cache.sizeGauge缓存当前条目数

标签示例:
name: 缓存名称(如 usersCache
result: 结果类型(hit/miss)

三、配置与自定义指标
1. 启用/禁用特定指标
# 禁用 JVM 内存指标
management.metrics.enable.jvm.memory.used=false
2. 添加自定义标签
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
    return registry -> registry.config()
        .commonTags("region", "us-east-1", "env", "prod");
}
3. 指标命名规则
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsNaming() {
    return registry -> registry.config()
        .namingConvention(NamingConvention.snakeCase);
}
四、监控数据展示示例(Prometheus)

/actuator/prometheus 端点获取的数据示例:

# HTTP 请求指标
http_server_requests_seconds_count{method="GET",uri="/api/users",status="200"} 42
http_server_requests_seconds_sum{method="GET",uri="/api/users",status="200"} 12.7

# JVM 内存使用
jvm_memory_used_bytes{area="heap",id="PS Eden Space"} 256000000
五、总结

核心价值
Micrometer 通过统一 API 屏蔽监控后端差异,开发者只需关注业务指标采集。
标准指标覆盖场景
JVM、HTTP、数据库、缓存等关键组件均已内置监控,开箱即用。
扩展性
通过自定义 MeterRegistryMeter 可集成私有监控系统。

springboot结合Micrometer

Spring Boot 集成 Micrometer 实现指标监控

Micrometer 是 Spring Boot 的官方监控工具库,通过 Actuator 模块提供开箱即用的指标采集能力。以下是完整的集成与自定义指标实现步骤:

一、添加依赖

pom.xml 中添加核心依赖(以 Prometheus 为例):

<!-- Spring Boot Actuator(暴露监控端点) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Micrometer 核心库 -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
</dependency>

<!-- 对接 Prometheus 的 Registry -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
二、配置监控端点

application.properties 中启用端点并配置 Prometheus:

# 暴露所有 Actuator 端点(生产环境建议按需暴露)
management.endpoints.web.exposure.include=*

# 配置应用名称(作为指标前缀)
management.metrics.tags.application=my-springboot-app

# 配置 Prometheus 抓取间隔
management.metrics.export.prometheus.step=30s
三、自动采集的指标

Spring Boot 会 自动生成以下指标(无需额外代码):

指标类型示例指标说明
JVM 监控jvm_memory_used_bytesJVM 内存使用量
HTTP 请求http_server_requests_secondsHTTP 接口耗时统计
数据库连接池jdbc_connections_active活跃数据库连接数
系统资源system_cpu_usage系统 CPU 使用率

访问 http://localhost:8080/actuator/prometheus 查看原始指标数据。

四、自定义业务指标
1. 计数器(Counter)统计订单创建次数
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Component;

@Component
public class OrderMetrics {
    private final Counter orderCreatedCounter;

    public OrderMetrics(MeterRegistry registry) {
        // 初始化计数器(带业务标签)
        orderCreatedCounter = Counter.builder("order.created")
                .description("订单创建次数统计")
                .tag("type", "online") // 静态标签
                .register(registry);
    }

    public void incrementOrderCreated(String userId) {
        // 动态添加标签(例如用户ID)
        orderCreatedCounter
            .bind(Tags.of("user", userId))
            .increment();
    }
}

在业务代码中调用:

@Autowired
private OrderMetrics orderMetrics;

public void createOrder(Order order) {
    // 业务逻辑...
    orderMetrics.incrementOrderCreated(order.getUserId());
}
2. 计时器(Timer)统计方法耗时

使用 @Timed 注解自动记录方法耗时:

import io.micrometer.core.annotation.Timed;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/users")
    @Timed(value = "user.fetch.all", description = "查询所有用户的耗时")
    public List<User> getAllUsers() {
        // 业务逻辑...
        return userService.findAll();
    }
}

或手动记录代码块耗时:

import io.micrometer.core.instrument.Timer;

public class PaymentService {
    private final Timer paymentTimer;

    public PaymentService(MeterRegistry registry) {
        paymentTimer = Timer.builder("payment.process.time")
                .description("支付处理耗时")
                .register(registry);
    }

    public void processPayment() {
        Timer.Sample sample = Timer.start(registry);
        try {
            // 支付业务逻辑...
        } finally {
            sample.stop(paymentTimer);
        }
    }
}
3. 仪表(Gauge)监控队列大小
import io.micrometer.core.instrument.Gauge;
import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.PostConstruct;
import java.util.Queue;

@Component
public class MessageQueueMetrics {
    private final Queue<Message> messageQueue;
    private final AtomicInteger queueSize = new AtomicInteger(0);

    public MessageQueueMetrics(Queue<Message> messageQueue, MeterRegistry registry) {
        this.messageQueue = messageQueue;
        // 注册 Gauge(动态获取队列大小)
        Gauge.builder("message.queue.size", queueSize, AtomicInteger::get)
                .description("消息队列当前大小")
                .register(registry);
    }

    @Scheduled(fixedRate = 5000)
    public void updateQueueSize() {
        queueSize.set(messageQueue.size());
    }
}
五、高级配置
1. 全局标签(区分环境/区域)
@Bean
public MeterRegistryCustomizer<MeterRegistry> globalTags() {
    return registry -> registry.config()
            .commonTags("env", "prod", "region", "us-east-1");
}
2. 过滤不需要的指标
@Bean
public MeterFilter excludeJvmThreadMetrics() {
    return MeterFilter.deny(id -> id.getName().startsWith("jvm.threads"));
}
3. 自定义指标命名规则
@Bean
public MeterRegistryCustomizer<MeterRegistry> namingConvention() {
    return registry -> registry.config()
            .namingConvention(NamingConvention.snakeCase);
}
六、验证与可视化
  1. 查看原始指标
    访问 http://localhost:8080/actuator/prometheus,搜索自定义指标(如 order_created_total)。

  2. 对接 Prometheus + Grafana
    • 在 prometheus.yml 中添加 Spring Boot 应用的抓取配置:

    scrape_configs:
      - job_name: 'spring-boot-app'
        metrics_path: '/actuator/prometheus'
        static_configs:
          - targets: ['localhost:8080']
    

    • 在 Grafana 中导入 Spring Boot 仪表板(如 ID 4701)。

七、总结

开箱即用:Spring Boot 自动采集 JVM、HTTP、DB 等核心指标。
灵活扩展:通过 CounterTimerGauge 轻松添加业务指标。
生产就绪:结合 Prometheus + Grafana 实现监控告警与可视化。

自定义一个Micrometer

在 Spring Boot 中自定义 Micrometer 的核心是创建 自定义的 MeterRegistry自定义指标采集逻辑。以下是详细步骤和代码示例:


一、自定义 MeterRegistry(监控数据上报)

1. 实现自定义注册中心
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.core.instrument.step.StepMeterRegistry;
import java.util.concurrent.TimeUnit;

public class CustomMeterRegistry extends StepMeterRegistry {
    private final CustomRegistryConfig config;

    public CustomMeterRegistry(CustomRegistryConfig config, Clock clock) {
        super(config, clock);
        this.config = config;
        // 设置命名规则(如转驼峰为下划线)
        config().namingConvention(NamingConvention.snakeCase);
        start(); // 启动后台线程
    }

    @Override
    protected void publish() {
        // 自定义上报逻辑(例如将指标发送到 Kafka 或 HTTP API)
        getMeters().forEach(meter -> {
            meter.match(
                gauge -> log.info("Gauge: {}={}", gauge.getId(), gauge.value()),
                counter -> log.info("Counter: {}={}", counter.getId(), counter.count()),
                timer -> log.info("Timer: {}={}s", timer.getId(), timer.totalTime(TimeUnit.SECONDS)),
                // 其他 Meter 类型处理...
                meter -> {}
            );
        });
    }

    @Override
    protected TimeUnit getBaseTimeUnit() {
        return TimeUnit.MILLISECONDS; // 定义时间单位
    }

    // 自定义配置类(继承 StepRegistryConfig)
    public static class CustomRegistryConfig extends StepRegistryConfig {
        public CustomRegistryConfig() {
            super("custom"); // 配置前缀为 "custom"
        }

        @Override
        public String prefix() {
            return "custom.metrics";
        }
    }
}
2. 注册自定义 Registry 到 Spring 上下文
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MetricsConfig {
    @Bean
    public CustomMeterRegistry customMeterRegistry() {
        CustomMeterRegistry.CustomRegistryConfig config = new CustomMeterRegistry.CustomRegistryConfig();
        return new CustomMeterRegistry(config, Clock.SYSTEM);
    }
}
3. 配置 application.properties
# 自定义 Registry 参数
custom.metrics.step=30s    # 数据上报间隔
custom.metrics.enabled=true

二、自定义指标采集逻辑

1. 创建自定义 Meter(例如统计缓存穿透次数)
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Component;

@Component
public class CacheMetrics {
    private final Counter cachePenetrationCounter;

    public CacheMetrics(MeterRegistry registry) {
        // 定义指标名称、描述、标签
        cachePenetrationCounter = Counter.builder("cache.penetration")
                .description("缓存穿透次数统计")
                .tag("cache", "userCache")
                .register(registry);
    }

    public void recordPenetration() {
        cachePenetrationCounter.increment();
    }
}

在业务代码中调用:

@Autowired
private CacheMetrics cacheMetrics;

public User getUserById(Long id) {
    User user = cache.get(id);
    if (user == null) {
        cacheMetrics.recordPenetration(); // 记录穿透事件
        user = database.load(id);
    }
    return user;
}
2. 自定义 MeterFilter(过滤或修改指标)
import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public MeterFilter renameTagFilter() {
        // 将标签名 "method" 改为 "http_method"
        return MeterFilter.renameTag("http.server.requests", "method", "http_method");
    }

    @Bean
    public MeterFilter denyTestEndpoints() {
        // 禁止统计 "/actuator" 端点的请求
        return MeterFilter.deny(id -> id.getName().startsWith("http.server.requests") 
            && id.getTag("uri") != null 
            && id.getTag("uri").startsWith("/actuator"));
    }
}
3. 动态标签(基于请求上下文)

使用 MeterFilter 添加动态标签(例如根据请求头添加租户 ID):

import org.springframework.web.servlet.HandlerInterceptor;

public class TenantTagInterceptor implements HandlerInterceptor {
    private final MeterRegistry registry;

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

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String tenantId = request.getHeader("X-Tenant-ID");
        if (tenantId != null) {
            // 为所有指标添加租户标签
            registry.config().commonTags("tenant", tenantId);
        }
        return true;
    }
}

注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MeterRegistry registry;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TenantTagInterceptor(this.registry));
    }
}

三、验证自定义效果

  1. 查看原始指标数据
    访问 /actuator/prometheus,搜索自定义指标(如 cache_penetration_total)。

  2. 日志验证
    如果自定义的 CustomMeterRegistry 实现了日志输出,检查日志中是否打印指标数据。

  3. 集成测试
    编写测试用例验证指标是否被正确记录:

@SpringBootTest
public class CacheMetricsTest {
    @Autowired
    private CacheMetrics cacheMetrics;

    @Autowired
    private MeterRegistry registry;

    @Test
    public void testCachePenetration() {
        cacheMetrics.recordPenetration();
        Counter counter = registry.find("cache.penetration").counter();
        assertThat(counter.count()).isEqualTo(1.0);
    }
}

四、注意事项

  1. 性能影响
    避免在 publish() 方法中执行阻塞操作(如同步 HTTP 请求),使用异步或批处理上报。

  2. 标签基数爆炸
    动态标签(如用户 ID)可能导致指标数量激增,建议仅用于低基数字段(如租户、区域)。

  3. 注册中心冲突
    如果同时使用多个 MeterRegistry(如 Prometheus 和自定义),确保指标不会重复上报。

  4. 命名规范
    遵循监控系统的命名规则(如 Prometheus 要求小写和下划线)。

通过以上步骤,你可以在 Spring Boot 中灵活自定义 Micrometer,适配私有监控系统或实现特定业务指标的采集。

关联知识

【Springboot知识】Springboot进阶-Actuator深入理解
【Micrometer官网地址】

相关文章:

  • wsl中迁移ubuntu24.04后docker后无法启动的问题
  • 聊一聊接口测试时需要注意哪些
  • FPAG_BUFFER学习
  • Elasticsearch入门指南(一)
  • zsh: command not found - 鸿蒙 HarmonyOS Next
  • Java 中 JSON 处理库将对象含二进制数组转换为 JSON 字符串
  • ROS2——foxy apt打包离线安装deb包
  • YOLOv11训练中精准率召回率与mAP@0.5的动态变化分析
  • 配置与管理代理服务器
  • openEuler-22.03-LTS-SP3 编译安装 Greenplum-db 6.20.0
  • 【检测手机有无网络】
  • 自动化测试——selenium
  • 【python】针对Selenium中弹框信息无法定位的问题,以下是综合解决方案及注意事项:
  • Trae + LangGPT 生成结构化 Prompt
  • C++ 时间库和线程库学习笔记(Chrono 与 Thread)
  • C++ 中的双指针技巧:高效解决数组和链表问题
  • 华为openEuler欧拉系统
  • unity运行时进行录制并保存(可进行二次加载包含场景中生成动态物体)
  • AMS 启动流程管理进程与Binder的关联
  • LeetCode.234. 回文链表
  • 哪个网站可以注册做男妓/seo软件优化
  • wordpress三合一主题/怎么优化自己公司的网站
  • 做网站虚拟主机和云服务器吗/南宁推广软件
  • 政府网站建设程序的设计原则不包括/谷歌google play官网
  • 开发电子商务网站的主流语言/石家庄网站建设培训
  • 中山网站建设/吉安seo网站快速排名