业务指标未注册导致 prometheus 抓不到:必须显式调用 prometheus.mustregister(),避免重复注册或类型误用(如活跃连接数该用 gauge 而非 counter),标签值需低基数且顺序严格匹配。

Go 服务暴露 /metrics 端点但 Prometheus 抓不到业务指标,不是配置或网络问题,而是指标根本没注册进采集器——90% 的失败卡在注册漏掉、重复注册、或类型用错这三步。
为什么 curl localhost:8080/metrics 只有 go_* 却没有你的 http_requests_total
默认的 promhttp.Handler() 只暴露运行时指标(go_goroutines、process_cpu_seconds_total 等),你定义的 httpReqCounter 如果没调 prometheus.MustRegister(),它就不存在于默认注册器里。
- 运行时指标自动注册;业务指标必须显式注册,且只允许一次
- 常见错误:把
prometheus.NewCounterVec()写在 handler 函数里,每次请求都新建+注册 → 启动 panic 或指标静默丢失 - 正确做法:声明为包级变量 + 在
init()或main()开头注册 - 别用
promauto.NewCounterVec就以为万事大吉——它只是帮你省了MustRegister调用,但依然要求变量是包级的,且不能跨包重复定义同名指标
Gin 中注册 /metrics 路由总返回 404 或空响应
http.ListenAndServe(":8080", nil) 不会自动挂载任何路由,prometheus.MustRegister() 也不等于暴露 HTTP 接口。必须显式绑定 handler 到路径。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 安全写法:
http.Handle("/metrics", promhttp.Handler())+http.ListenAndServe(":8080", nil) - 更推荐新建独立 mux:
mux := http.NewServeMux(); mux.Handle("/metrics", promhttp.Handler()); http.ListenAndServe(":8080", mux),避免污染http.DefaultServeMux - 若用 Gin:
r.GET("/metrics", gin.WrapH(promhttp.Handler()));Echo 则用e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) - 路径不必非得是
/metrics,但需和 Prometheus 配置中scrape_configs.job.metrics_path严格一致
用 CounterVec 统计状态码却导致指标爆炸
直接用 r.StatusCode 当 label 值,会导致每个新状态码(比如 429123)都生成一个新时间序列,Prometheus server 内存和查询性能迅速崩坏。
- label 值必须是低基数、预定义集合,例如
"200"、"404"、"500"、"other" - 不要用
strconv.Itoa(r.StatusCode)直接转,而是用switch映射常见码,非标统一归入"other" - 路径、用户 ID、UUID 绝对不能进 label —— 这是 cardinality problem 的高发区
- 标签名必须全小写、下划线分隔(如
status_code),不能含-或大写字母
活跃连接数该用 Counter 还是 Gauge?
用 Counter 统计“当前在线人数”或 WebSocket 连接数,等于埋雷:它只能增不能减,goroutine 退出后指标永远卡在高位,监控完全失真。
- 活跃连接、内存用量、线程数等瞬时值,必须用
prometheus.NewGauge() - 每个 goroutine 启动时
.Inc(),退出时必须.Dec();漏掉Dec()就等于泄漏指标 - 别拿
Gauge当Counter用(比如每次请求.Set(1)),语义混乱、聚合失真 - 如果用
CounterVec记录“总连接建立次数”,那是对的;但“当前连接数”只能是Gauge
最常被忽略的一点:所有带标签的指标,WithLabelValues("a", "b") 传入的顺序和数量,必须和定义时 []string{"a", "b"} 完全一致,错一位或少一个,指标就静默丢弃,且无任何报错提示。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










