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 数据源
- Configuration → Data Sources → Add data source
- 选择 Prometheus
- URL:
http://host.docker.internal:8428 - 点击 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 验证
- VictoriaMetrics UI:http://localhost:8428/vmui
- 查询:
{application="demo"}或app_requests_total
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 创建面板
- Dashboards → New → New Dashboard
- Add visualization
- 选择数据源
- 切换到 Code 模式,输入 PromQL
- 选择可视化类型(Stat/Time series/Gauge)
- 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 |

浙公网安备 33010602011771号