go服务暴露prometheus指标应使用promhttp.handler()挂载/metrics路由,注册指标须在http服务启动前完成;sla相关指标用counter统计请求状态、histogram记录耗时(勿用summary),buckets需覆盖sla目标;prometheus抓取需确保网络可达、路径正确(/metrics)、_bucket全量采集;告警规则须用rate()配合守卫条件防误报。

Go服务里怎么暴露Prometheus指标
直接用 promhttp 包挂一个 HTTP handler 就行,别自己造轮子。它自动处理 /metrics 请求、序列化所有注册的指标,还带基础的 Content-Type 和缓存头。
常见错误是监听了端口但没注册指标,或者注册了却忘了调 http.Handle("/metrics", promhttp.Handler()) —— 结果访问 /metrics 返回 404 或空响应。
- 必须在启动 HTTP server 前完成指标注册(比如
prometheus.NewCounterVec) - 不要在 handler 里动态创建新指标,会 panic;复用已注册的
CounterVec或GaugeVec - 如果服务已有路由框架(如 Gin),用
gin.WrapH(promhttp.Handler()),别直接c.Data手动写响应
哪些指标算 SLA 相关,该用 Counter 还是 Histogram
SLA 关注的是“请求是否成功”和“耗时是否达标”,不是资源占用率。所以重点暴露两类指标:http_requests_total(带 status、method、path 标签的 Counter)和 http_request_duration_seconds(Histogram)。
别用 Summary:它不支持 Prometheus 的 rate() 和分位数聚合,查 P99 耗时会不准;也别把状态码塞进 Histogram 的 label_values —— Histogram 本身不支持多维标签,得靠 http_requests_total 分状态统计成功率。
立即学习“go语言免费学习笔记(深入)”;
-
Counter记成功/失败次数:用counter.WithLabelValues("200"),别用字符串拼接 key -
Histogram记耗时:桶(Buckets)要覆盖你的 SLA 目标,比如 SLA 是 200ms,就至少设[]float64{0.05, 0.1, 0.2, 0.5} - 避免高频打点:HTTP 中间件里别对每个请求都调
histogram.Observe()后再 return,panic 会导致指标丢失;用defer确保执行
Prometheus 配置里怎么抓 Go 服务的指标
关键不是加 job,而是确认 target 能连通、路径正确、且指标格式合法。Prometheus 抓不到指标,80% 是网络或路径问题,不是配置写错。
常见错误包括:Go 服务监听 127.0.0.1:8080,但 Prometheus 在容器外跑,连不上;或者 metrics 路径配成 /actuator/prometheus(Spring Boot 风格),而 Go 服务只暴露 /metrics。
- 检查
scrape_configs中的static_configs.targets是否指向服务真实 IP + 端口(不是 localhost) - 务必加
metrics_path: "/metrics",即使默认也显式写上,避免被其他 job 覆盖 - 如果服务启用了 Basic Auth,得配
basic_auth;如果走 HTTPS,记得开insecure_skip_verify: true(仅测试环境)
告警规则里怎么写 SLA 违规判断
SLA 通常是“99% 请求耗时 ≤ 200ms”,对应 Prometheus 表达式是:histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[1h])) by (le)) > 0.2。但直接这么写会误报——因为刚启动的服务没数据,或某段时间无流量,rate() 返回空。
真正要监控的是“持续一段时间内”的达标率,不是瞬时值。所以必须加 and on() (count by() (rate(http_requests_total[1h])) > 0) 这类守卫条件,排除低流量干扰。
- 别用
irate():它取最近两个点,抖动大,SLA 场景必须用rate() - 时间窗口选 1h 或 5m,取决于你的 SLA 定义周期;别用
[1m],太短,噪声大 - 告警
for至少设 5m:避免单次毛刺触发,也给修复留出时间
最易忽略的一点:Histogram 的 _bucket 指标必须全量被抓取,漏掉任意一个桶(比如最高桶没打点),histogram_quantile() 就会返回 NaN —— 告警永远不触发。上线前用 curl http://your-go-service/metrics | grep _bucket 确认桶齐全。










