Windows 下基于 Docker 安装 Spring Boot 可观测性系统(VictoriaMetrics + grafana)

Windows 下基于 Docker 安装 Spring Boot 可观测性系统

架构概览

Spring Boot App
        ↓
   两种模式可选:
   1. Pull 模式:VictoriaMetrics 主动抓取 /actuator/prometheus
   2. Push 模式:应用主动推送指标到 VictoriaMetrics
        ↓
VictoriaMetrics (存储指标)
        ↓
Grafana (查询并展示)

一、基础组件安装

1.1 Docker 镜像加速配置(国内网络需要)

Docker Desktop → Settings → Docker Engine,添加:

{
  "registry-mirrors": ["https://docker.1ms.run"]
}

1.2 安装 Grafana

docker run -d --name grafana -p 3000:3000 -v grafana-storage:/var/lib/grafana grafana/grafana:latest

访问 http://localhost:3000,默认账号密码:admin/admin

1.3 配置 Grafana 数据源

  1. Configuration → Data Sources → Add data source
  2. 选择 Prometheus
  3. URL:http://host.docker.internal:8428
  4. 点击 Save & Test

二、Pull 模式(VictoriaMetrics 主动抓取)

适用场景:服务数量固定,网络环境简单

2.1 创建抓取配置文件

创建 D:\victoriametrics\prometheus.yml

scrape_configs:
  - job_name: 'spring-boot-app'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    static_configs:
      - targets: ['host.docker.internal:8888']

2.2 启动 VictoriaMetrics

docker run -d --name victoriametrics -p 8428:8428 -v vmdata:/storage -v D:\victoriametrics\prometheus.yml:/etc/prometheus/prometheus.yml victoriametrics/victoria-metrics:latest "-storageDataPath=/storage" "-promscrape.config=/etc/prometheus/prometheus.yml"

2.3 Spring Boot 配置

pom.xml 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

application.properties

server.port=8888
spring.application.name=demo

# Actuator 配置
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

2.4 验证

2.5 多服务配置(基于文件的服务发现)

修改 D:\victoriametrics\prometheus.yml

scrape_configs:
  - job_name: 'spring-boot-apps'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    file_sd_configs:
      - files:
          - '/etc/prometheus/targets/*.json'
        refresh_interval: 30s

创建 D:\victoriametrics\targets\apps.json

[
  {
    "targets": ["host.docker.internal:8888"],
    "labels": {"app": "demo", "env": "dev"}
  },
  {
    "targets": ["host.docker.internal:8889"],
    "labels": {"app": "user-service", "env": "dev"}
  }
]

启动命令:

docker run -d --name victoriametrics -p 8428:8428 -v vmdata:/storage -v D:\victoriametrics\prometheus.yml:/etc/prometheus/prometheus.yml -v D:\victoriametrics\targets:/etc/prometheus/targets victoriametrics/victoria-metrics:latest "-storageDataPath=/storage" "-promscrape.config=/etc/prometheus/prometheus.yml"

三、Push 模式(应用主动推送)

适用场景:微服务数量多、动态扩缩容、不想维护抓取配置

3.1 启动 VictoriaMetrics(无需抓取配置)

docker run -d --name victoriametrics -p 8428:8428 -v vmdata:/storage victoriametrics/victoria-metrics:latest "-storageDataPath=/storage"

3.2 Spring Boot 配置

pom.xml 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-influx</artifactId>
</dependency>

application.properties

server.port=8888
spring.application.name=demo

# Actuator 配置
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

# 推送模式配置
management.metrics.export.influx.enabled=true
management.metrics.export.influx.uri=http://localhost:8428/write
management.metrics.export.influx.db=default
management.metrics.export.influx.step=5s
management.metrics.export.influx.auto-create-db=false

# 添加服务标签,区分不同微服务
management.metrics.tags.application=${spring.application.name}
management.metrics.tags.instance=${spring.application.name}:${server.port}

3.3 验证

3.4 Push 模式优势

  • 新服务启动自动上报,无需修改 VictoriaMetrics 配置
  • 支持动态扩缩容
  • 可控制推送频率
  • 适合 Kubernetes 等动态环境

四、自定义埋点

4.1 埋点类型

类型 说明 适用场景
Counter 只增不减的计数器 请求次数、错误次数
Gauge 可增可减的仪表盘 在线人数、队列大小
Timer 计时器 接口耗时、方法执行时间

4.2 代码示例

package com.example.demo.metrics;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

@Component
public class CustomMetrics {

    private final Counter requestCounter;
    private final Timer requestTimer;
    private final AtomicInteger activeUsers = new AtomicInteger(0);

    public CustomMetrics(MeterRegistry registry) {
        // Counter - 计数器
        this.requestCounter = Counter.builder("app_requests_total")
                .description("Total number of requests")
                .tag("type", "api")
                .register(registry);

        // Timer - 计时器
        this.requestTimer = Timer.builder("app_request_duration")
                .description("Request duration")
                .tag("endpoint", "default")
                .register(registry);

        // Gauge - 仪表盘
        Gauge.builder("app_active_users", activeUsers, AtomicInteger::get)
                .description("Current active users")
                .register(registry);
    }

    public void incrementRequestCount() {
        requestCounter.increment();
    }

    public Timer.Sample startTimer() {
        return Timer.start();
    }

    public void stopTimer(Timer.Sample sample) {
        sample.stop(requestTimer);
    }

    public void userLogin() {
        activeUsers.incrementAndGet();
    }

    public void userLogout() {
        activeUsers.decrementAndGet();
    }
}

4.3 使用示例

@RestController
@RequestMapping("/metrics-test")
public class MetricsTestController {

    private final CustomMetrics customMetrics;

    public MetricsTestController(CustomMetrics customMetrics) {
        this.customMetrics = customMetrics;
    }

    @GetMapping("/request")
    public String testRequest() throws InterruptedException {
        Timer.Sample sample = customMetrics.startTimer();
        customMetrics.incrementRequestCount();
        
        // 模拟业务处理
        Thread.sleep(new Random().nextInt(200));
        
        customMetrics.stopTimer(sample);
        return "Request processed";
    }

    @GetMapping("/login")
    public String login() {
        customMetrics.userLogin();
        return "User logged in";
    }

    @GetMapping("/logout")
    public String logout() {
        customMetrics.userLogout();
        return "User logged out";
    }
}

五、Grafana 面板配置

5.1 常用 PromQL 查询

# 每分钟请求数
rate(app_requests_total[1m]) * 60

# 每15秒请求增量
increase(app_requests_total[15s])

# 平均响应时间(秒)
rate(app_request_duration_seconds_sum[1m]) / rate(app_request_duration_seconds_count[1m])

# P95 响应时间
histogram_quantile(0.95, rate(app_request_duration_seconds_bucket[1m]))

# 当前活跃用户
app_active_users

# 按应用过滤(Push 模式)
app_requests_total{application="demo"}

5.2 创建面板

  1. Dashboards → New → New Dashboard
  2. Add visualization
  3. 选择数据源
  4. 切换到 Code 模式,输入 PromQL
  5. 选择可视化类型(Stat/Time series/Gauge)
  6. Apply 保存

5.3 设置自动刷新

Dashboard 右上角刷新图标旁边的下拉框,选择 5s


六、两种模式对比

特性 Pull 模式 Push 模式
配置复杂度 需要维护抓取配置 应用自带配置
服务发现 需要配置 targets 自动注册
适合场景 服务固定、数量少 微服务、动态扩缩容
数据延迟 取决于抓取间隔 取决于推送间隔
网络要求 VM 能访问应用 应用能访问 VM

七、常用命令

# 查看容器状态
docker ps -a

# 查看日志
docker logs victoriametrics
docker logs grafana

# 重启容器
docker restart victoriametrics
docker restart grafana

# 删除容器
docker rm -f victoriametrics
docker rm -f grafana

八、访问地址汇总

服务 地址
Spring Boot 指标 http://localhost:8888/actuator/prometheus
VictoriaMetrics UI http://localhost:8428
VictoriaMetrics vmui http://localhost:8428/vmui
VictoriaMetrics Targets http://localhost:8428/targets
Grafana http://localhost:3000
posted @ 2026-01-21 18:39  Me无情  阅读(0)  评论(0)    收藏  举报