主题
30 · Prometheus + Grafana
目标:给 Go API 暴露
/metrics,用 Prometheus 拉取,在 Grafana 看 QPS / 延迟 / 错误率。
前置:14 · Zap · 18 · 串烧 · 22 · Docker
官方:Prometheus · Grafana · Go:prometheus/client_golang
1. 三类可观测别混
| 信号 | 回答什么 | 本篇 |
|---|---|---|
| Metrics | 有多忙、多慢、多错 | Prometheus |
| Logs | 某次请求发生了什么 | Zap(14) |
| Traces | 请求跨过哪些服务 | OTel(31) |
Node 对照:prom-client + Grafana。
2. 指标类型(先会用)
| 类型 | 用途 | 例子 |
|---|---|---|
| Counter | 只增 | 请求总数、错误数 |
| Gauge | 可上可下 | 协程数、队列积压 |
| Histogram | 分布 | 请求延迟桶 |
RED 入门法:Rate(QPS)、Errors、Duration。
3. Go 暴露 metrics
bash
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp
go get github.com/prometheus/client_golang/prometheus/promauto1
2
3
2
3
go
var (
httpRequests = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "http_requests_total",
Help: "HTTP requests",
}, []string{"method", "path", "code"})
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Latency",
Buckets: prometheus.DefBuckets,
}, []string{"method", "path"})
)
// Gin 中间件里:计时 → Observe;结束后 Inc counter
// 独立路由:
r.GET("/metrics", gin.WrapH(promhttp.Handler()))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
标签基数:不要把 userId、noteId 当 label → 时间序列爆炸。
4. Compose:Prometheus + Grafana
prometheus.yml:
yaml
global:
scrape_interval: 15s
scrape_configs:
- job_name: notesapi
static_configs:
- targets: ["api:8080"] # Compose 服务名1
2
3
4
5
6
2
3
4
5
6
yaml
prometheus:
image: prom/prometheus:v2.54.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:11.1.0
ports:
- "3000:3000"
depends_on:
- prometheus1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
Grafana:加数据源 Prometheus → http://prometheus:9090 → 面板查询:
promql
sum(rate(http_requests_total[1m])) by (path)
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, path))1
2
2
5. 动手清单
- [ ]
/metrics能 curl 出http_requests_total - [ ] Prometheus Targets 状态 UP
- [ ] Grafana 一张 QPS 图 + 一张 P95 延迟图
- [ ] 故意 404/500,错误率曲线有反应
- [ ] 能讲清:为何不用高基数 label
6. 项目驱动
| 场景 | 指标 |
|---|---|
| 笔记 API | RED + DB 查询耗时(可选) |
| Asynq Worker | 处理成功/失败 Counter、队列 Gauge |
| 导出任务 | 进行中 Gauge |
面试口述:「用 Histogram 看 P95,不靠感觉说慢。」
7. 常见坑 + AI 审查
| 坑 | 说明 |
|---|---|
| 路径含 ID 当 label | 用路由模板 /notes/:id → /notes/:id |
| 只暴露 metrics 不上抓取 | 要配 scrape |
| Grafana 密码默认 admin | 改掉;仅本地可临时 |
| AI 引入十几个无用指标 | 先 RED,再加业务 |
| 与健康检查混淆 | /health ≠ /metrics |
8. 下一篇
一次请求串起来看:
→ 31 · OpenTelemetry 链路追踪
