
Go 微服务怎么把指标塞进 Grafana
Grafana 本身不采集数据,它只负责展示。你得先让 Go 服务把指标暴露出来,Grafana 才能拉。最常用、最轻量的方式是用 prometheus/client_golang 暴露 /metrics HTTP 端点,再配 Prometheus 抓取,最后在 Grafana 里连上 Prometheus 数据源。
常见错误现象:curl http://localhost:8080/metrics 返回 404 或空响应;Grafana 显示 “No data”;Prometheus 的 Targets 页面显示 DOWN。
- 确保注册了
promhttp.Handler()到 HTTP 路由,比如http.Handle("/metrics", promhttp.Handler()) - 检查端口是否被其他服务占用,或防火墙是否拦截(本地开发常忽略
http.ListenAndServe(":8080", nil)后没加log.Fatal导致进程静默退出) - Go 服务启动后,先手动
curl -v http://localhost:8080/metrics,看到一堆# HELP行才算基础通了 - 不要用
http.DefaultServeMux外挂中间件(如日志、CORS),某些中间件会吞掉 HEAD 请求,导致 Prometheus 抓取失败
哪些 Go 指标值得暴露给全链路看板
不是所有指标都该上 Grafana。全链路监控关注的是“请求流经路径上的健康状态”,不是单个 goroutine 的内存细节。重点暴露三类:服务维度、HTTP 维度、业务关键路径维度。
使用场景:你想在 Grafana 看到“用户下单接口在 service-order 中 P95 延迟突增”,而不是“runtime.GC 耗时”这种通用指标(除非它真成了瓶颈)。
立即学习“go语言免费学习笔记(深入)”;
-
http_request_duration_seconds_bucket(带handler、method、status标签)——必须有,它是链路延迟分析的基石 -
http_requests_total(同上标签)——配合 rate() 算 QPS,识别流量异常 - 自定义业务指标,比如
order_created_total{region="cn-east"},注意用promauto.NewCounter避免重复注册 - 避免暴露高基数标签,比如
user_id或request_id,会导致 Prometheus 内存暴涨甚至 OOM
Grafana 看板里 Go 指标查不出来?检查这几点
指标暴露了、Prometheus 抓到了、Grafana 数据源也选对了,但查询语句始终空——大概率是 label 匹配不上,或者聚合逻辑写反了。
典型错误现象:图表显示 “No data”,但 Prometheus Graph 页面能查出原始时间序列;或 P95 曲线是一条直线(值恒为 0)。
- 确认 Prometheus 查询表达式用了正确的 label 过滤,比如
rate(http_requests_total{job="service-order"}[5m]),漏掉{job="..."}就可能跨服务混算 - 延迟直方图要用
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="service-order"}[5m])) by (le)),少一层sum ... by (le)会返回空 - Grafana 变量(如
$service)传入查询时,检查是否启用了 “Multi-value” 却没加...{job=~"$service"}中的=~ - Prometheus 默认只保留 15 天数据,如果看板时间范围选了“过去 30 天”,自然查不到
Go 服务重启后 Grafana 图表断层?不是丢数,是 counter 重置
Go 的 prometheus.Counter 是单调递增的,但服务重启后会从 0 开始。Prometheus 的 rate() 和 increase() 函数能自动处理这种重置,前提是抓取间隔稳定、且重置发生在两个样本之间。
性能影响:如果服务频繁启停(比如本地 debug 模式每分钟重启),rate() 可能误判为“突增归零”,导致图表毛刺或负值。
- 生产环境务必启用
--web.enable-admin-api并配置 Prometheus 的scrape_timeout(建议 ≤ 10s)和scrape_interval(建议 15s),避免因超时错过重置点 - 不要在 Grafana 里直接画
http_requests_total原始值(它是一条斜率不断变陡的线),而应始终用rate(...[5m]) - 若需观察累计总量(如“今天总共处理多少订单”),用 Prometheus 的 recording rule 预计算
sum(increase(order_created_total[1d])),再喂给 Grafana
最易被忽略的一点:Grafana 查询里的 [5m] 是指“最近 5 分钟内 Prometheus 自己抓到的数据点”,不是“服务运行的最近 5 分钟”。如果抓取失败过,这段窗口就缺样本,rate() 会直接返回空——得去 Prometheus 的 Status > Targets 页面盯住你的 job 是否稳定为 UP。










