必须显式注册指标(如NewGoCollector)、挂载promhttp.Handler()到/metrics、监听0.0.0.0,三者缺一不可;否则Prometheus抓取返回404、空页或target为down。

为什么直接用 Prometheus 抓不到 Go 应用的指标?
不是配置写错了,而是 Go 程序默认根本不暴露任何指标。Prometheus 是 pull 模式,它会定时访问 /metrics 路径,但如果你没在 Go 服务里显式注册并启动这个 endpoint,返回就是 404 —— 这是最常见的“监控数据为空”根源。
- 必须手动引入
prometheus/client_golang并注册http.Handle("/metrics", promhttp.Handler()) - 如果用了 Gin、Echo 等框架,不能直接用
http.ListenAndServe,得把promhttp.Handler()挂到对应路由组下(比如 Gin 的r.GET("/metrics", gin.WrapH(promhttp.Handler()))) - 别忘了在容器里监听
0.0.0.0:8080,而不是127.0.0.1:8080,否则 Pod 内部网络无法被 Prometheus 抓取
ServiceMonitor 不生效?先检查这三件事
ServiceMonitor 是 Operator 模式下自动发现 Go 服务的关键,但它不会“自动生效”,依赖严格匹配。
-
selector.matchLabels必须和你 Go 服务的Service的metadata.labels完全一致,一个字母都不能错 - 确保
Service的spec.ports[].name和ServiceMonitor.spec.endpoints[].port名字相同(例如都叫web-metrics),不是端口号 - 确认
ServiceMonitor和Service在同一个命名空间,或设置了正确的namespaceSelector;Operator 默认只读本 namespace
Go 服务暴露指标时,counter 和 gauge 到底怎么选?
选错类型会导致 PromQL 查询结果完全失真。这不是风格问题,是语义错误。
-
counter只能单调递增,适合请求数、错误总数等累积值;用rate()计算 QPS,比如rate(http_requests_total{job="my-go-app"}[5m]) -
gauge可增可减,适合当前连接数、内存占用、队列长度;直接用avg_over_time()或瞬时值分析 - 千万别把响应延迟(histogram)硬塞进
gauge——要用prometheus.NewHistogramVec,否则histogram_quantile()函数失效
Kubernetes 中 Go 应用的指标延迟高,别急着调 scrape_interval
抓取延迟高,90% 情况不是 Prometheus 配置问题,而是 Go 服务本身卡在指标收集环节。
- 检查是否在
Collect()方法里做了同步阻塞操作(比如调用外部 HTTP 接口、查数据库)——这会让整个/metrics响应变慢,拖垮所有目标 - 避免在指标采集路径中做日志打印或复杂计算;指标应是轻量、无副作用的快照
- 如果必须采集耗时数据,改用异步 goroutine + 缓存(比如每 10s 更新一次缓存值,
/metrics只读缓存)
prometheus.MustRegister()。



















