根本原因是未调用prometheus.mustregister()注册自定义指标,仅挂载/metrics路由只能暴露go运行时指标;必须在http.listenandserve()前完成注册,且标签名、顺序、值需严格一致,否则指标静默丢失。

Go 服务暴露 /metrics 但 Prometheus 抓不到业务指标,不是配置或网络问题,而是指标根本没注册进采集器——90% 的集成失败卡在注册这一步。
为什么 curl localhost:8080/metrics 有数据却没你的业务指标?
默认的 promhttp.Handler() 只暴露 go_*、process_* 这类运行时指标。你定义的 httpReqCounter 如果没调用 prometheus.MustRegister(),它就不存在于默认注册器里。
- 运行时指标(goroutines、GC、内存等)不会自动注册,必须显式调用
prometheus.MustRegister(prometheus.NewGoCollector())和prometheus.MustRegister(prometheus.NewProcessCollector(...)) - 自定义指标必须是包级变量,且只注册一次;写在 handler 函数里会导致 panic:
duplicate metrics collector registration - 若用了自定义注册器(如
reg := prometheus.NewRegistry()),必须用promhttp.HandlerFor(reg, ...),否则/metrics返回空
http.ListenAndServe() 传 promhttp.Handler() 编译报错?
错误提示类似 cannot use promhttp.Handler() (value of type http.Handler) as type func(http.ResponseWriter, *http.Request),是因为 http.ListenAndServe() 第二个参数接受 nil 或函数类型,而 promhttp.Handler() 返回的是 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:
router.GET("/metrics", gin.WrapH(promhttp.Handler()));Echo:e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
用 CounterVec 打状态码维度时为啥指标爆炸?
直接用 r.StatusCode 当 label 值,会导致每个新状态码(比如 429123)都生成一个新时间序列,Prometheus server 内存和查询性能迅速崩坏。
- label 值必须是低基数、预定义集合,例如
"200"、"404"、"500"、"other" - 别用
strconv.Itoa(r.StatusCode)直接转,而是用switch映射常见码,非标统一归入"other" - 路径、用户 ID、UUID 绝对不能进 label —— 这是 cardinality problem 的高发区
活跃连接数该用 Counter 还是 Gauge?
用 Counter 统计“当前在线人数”或 WebSocket 连接数,等于埋雷:它只能增不能减,goroutine 退出后指标永远卡在高位,监控完全失真。
- 活跃连接、内存用量、线程数等瞬时值,必须用
prometheus.NewGauge() - 每个 goroutine 启动时
.Inc(),退出前必须.Dec()(注意并发安全,建议用.Sub(1)配合 defer) - 如果用
Counter记累计请求数、错误总数这类只增不减的量,才是语义正确的
最容易被忽略的是:指标注册顺序和注册器绑定必须严格一致;标签值一旦引入高基数字段,问题不会立刻暴露,但几小时后 Prometheus 查询会变慢、内存暴涨,排查成本极高。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










