必须显式注册业务指标并挂载promhttp.Handler()到/metrics,否则仅暴露Go运行时指标;自定义指标需在init()或main()中注册,用CounterVec/HistogramVec按method、status等标签统计,避免高基数。

暴露 /metrics 端点是前提,但光挂 promhttp.Handler() 不够
只注册 promhttp.Handler() 会暴露 Go 运行时指标(如 go_goroutines、go_memstats_alloc_bytes),但业务逻辑的请求量、错误率、延迟等关键数据不会自动上报。必须手动定义并注册业务指标。
- 用
prometheus.NewCounterVec或prometheus.NewHistogramVec定义带标签的指标,比如按method、endpoint、status切分 - 在 HTTP handler 内调用
.WithLabelValues(...).Inc()或.Observe(duration.Seconds())更新指标 - 确保
init()或main()中调用prometheus.MustRegister(...),否则指标不会出现在/metrics输出里 - 避免在热路径上重复调用
WithLabelValues—— 它返回新对象,高频创建会增加 GC 压力;应提前缓存常用 label 组合的子指标
Counter 和 Histogram 的选型直接影响延迟分析能力
很多人用 Counter 记录“总耗时”,再靠 PromQL 除以请求数算平均延迟,这是错的 —— 平均值掩盖分布,无法识别长尾问题。
- 对延迟类指标,必须用
Histogram(不是Summary),它按预设桶(如0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10秒)统计频次,支持计算P90、P99 -
Counter只适合计数类场景:请求总数、错误总数、重试次数 - 别把业务状态(如“订单是否支付成功”)硬塞进
Counter标签 —— 标签维度爆炸会导致 Prometheus 内存飙升甚至 OOM - 如果真需要布尔状态监控,用
Gauge更合适,且应控制标签组合不超过 3–4 个
Grafana 里查不到指标?先确认 Prometheus 抓取目标是否 healthy
常见现象是 Go 服务已启动、/metrics 能 curl 通,但 Grafana 面板空或报 “No data”。问题往往不在 Grafana,而在抓取链路断了。
- 访问
http://<prometheus-url>/targets</prometheus-url>,检查对应 job 的 State 是否为UP;若为DOWN,点进去看 Last Scrape Error - 典型错误:
server returned HTTP status 404 Not Found(Go 服务没挂/metrics)、context deadline exceeded(网络不通或超时)、connection refused(端口未监听或防火墙拦截) - Prometheus 默认抓取间隔是 1m,但 Go 服务刚启动时指标可能还没被采集到 —— 等 2 分钟再查,或临时改小
scrape_interval测试 - 如果服务跑在 Kubernetes 里,确认 Service 的
targetPort和 Pod 的实际监听端口一致,且podSelector匹配正确
业务指标命名和标签设计,决定了后期 PromQL 查询成本
名字起得随意、标签滥用,会让后续写查询变得极其痛苦,甚至无法聚合。
- 指标名用下划线分隔、全小写,遵循
<namespace>_<subsystem>_<name></name></subsystem></namespace>规范,例如payment_service_http_requests_total,而非myapp_req_count - 标签要真正用于过滤或分组,避免冗余字段 —— 比如
version标签只有发版时才变,日常查询几乎不用,就不该加 - 高基数标签(如
user_id、request_id)严禁使用,它们会让时间序列数量爆炸,拖垮 Prometheus 性能 - 同一语义的标签键在所有指标中保持一致,比如都用
status而不是有的用http_status、有的用code

















