Prometheus+Grafana是Go微服务监控主流方案,需用官方SDK暴露规范指标端点,通过中间件自动埋点、路由归一化、禁用健康接口埋点,告警逻辑应写在Prometheus而非Go代码中。

用 Prometheus + Grafana 搭监控,别自己造轮子
Go 微服务监控的主流方案是 Prometheus 拉取指标 + Grafana 可视化 + Alertmanager 告警,不是用 Go 写个 HTTP 接口吐 JSON 就算监控了。自己维护指标采集、存储、聚合、告警路由,成本远高于集成标准栈。
关键点在于:Go 服务要暴露符合 Prometheus 规范的指标端点,其他交给基础设施。
-
github.com/prometheus/client_golang是官方 SDK,必须用它,不要手写/metrics响应 - 默认指标(如 goroutines 数、GC 次数、HTTP 请求延迟)开箱即用,调
promhttp.Handler()即可暴露 - 自定义业务指标(比如订单处理失败数)要用
prometheus.NewCounterVec()或NewHistogramVec(),注意 label 维度别设计太宽(如用用户 ID 当 label 会爆炸)
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
orderCount = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "order_processed_total",
Help: "Total number of orders processed",
},
[]string{"status"}, // 只用 status,不用 user_id
)
)
func init() {
prometheus.MustRegister(orderCount)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/process", func(w http.ResponseWriter, r *http.Request) {
orderCount.WithLabelValues("success").Inc()
w.WriteHeader(http.StatusOK)
})
http.ListenAndServe(":8080", nil)
}
HTTP 中间件自动埋点,避免每个 handler 手动统计
手动在每个 handler 里调 httpDuration.WithLabelValues(...).Observe(...) 容易漏、难维护。应该用中间件统一采集请求路径、方法、状态码、延迟。
注意:promhttp.InstrumentHandlerDuration 等内置中间件只适合简单场景;高并发下需避免在每次请求中新建 prometheus.Labels map,应复用或预分配。
立即学习“go语言免费学习笔记(深入)”;
- 用
promhttp.InstrumentHandlerDuration+promhttp.InstrumentHandlerCounter覆盖 80% 场景 - 路径带参数(如
/user/:id)时,务必先做路由归一化(例如把/user/123→/user/{id}),否则指标维度爆炸 - 不要对健康检查接口(
/healthz)埋点——它高频调用会污染真实业务指标
告警规则写在 Prometheus,不在 Go 里触发 HTTP 请求
常见错误:在 Go 代码里监听某个条件(如错误率 > 5%),然后 http.Post("http://alert-svc/notify")。这绕过了 Prometheus 的去重、静默、分组、抑制等核心能力,极易重复告警、漏告警。
正确做法是把告警逻辑全写进 alert.rules.yml,由 Prometheus 定期评估并推给 Alertmanager:
- 告警表达式用
rate(http_request_duration_seconds_count{job="my-service"}[5m])这类 PromQL,不是 Go 里的 if 判断 - 告警 label(如
severity: "critical")和 annotations(如summary: "High error rate on {{ $labels.instance }}")都在 YAML 里定义 - Go 服务只需确保指标可被 Prometheus 正确抓取(检查
scrape_configs和目标状态页/targets)
本地开发时用 docker-compose 快速验证整套链路
不启动完整 K8s 集群也能验证监控是否生效:用 docker-compose 跑 prometheus、grafana、alertmanager 和你的 Go 服务,5 分钟内就能看到指标和告警。
容易卡住的点:
- Prometheus 抓不到 Go 服务?检查容器网络:Go 服务暴露的
:8080/metrics是否能被 Prometheus 容器 curl 通(docker exec -it prometheus curl http://go-service:8080/metrics) - Grafana 查不到数据?确认数据源已添加且指向
http://prometheus:9090(不是localhost) - Alertmanager 没收到告警?看 Prometheus UI 的
Status > Alerts页面是否显示FIRING,再查 Alertmanager 的/alerts接口
最常被忽略的是指标生命周期管理:上线新服务要加 job,下线旧服务要及时删 job,否则 Prometheus 会持续报 target down 错误,干扰真实问题定位。









