go微服务可观测性需指标、追踪、日志在请求生命周期中上下文对齐,否则metrics与trace不一致;tracer初始化必须早于handler注册;histogram应避免cardinality爆炸;/metrics端点须正确暴露指标。

为什么 http_requests_total 和实际 trace 数量对不上
常见现象:Prometheus 里 http_requests_total 每秒涨 100,但 Jaeger 中只看到 30 条 trace,且部分 trace 缺失 span。根本原因是指标计数和 trace 生命周期没绑定在同一 context 上。
- 只在 handler 开头调用
httpRequestsTotal.Inc(),但中间件 panic 或 early return 时 trace 已创建却未上报,而计数已增加 - 多个中间件各自调用 Inc(),比如 auth 中间件 + rate limit 中间件都计了一次,但最终只走一个 trace
- 没有用
WithLabelValues(r.Method, r.URL.Path, strconv.Itoa(statusCode))动态打标,导致所有错误都被归到 “200” 分组里,掩盖真实失败率
正确做法:把计数逻辑塞进 tracing middleware 的 defer span.Finish() 前一刻,并从 span 状态中提取 HTTP 状态码;或者统一用 promhttp.InstrumentHandlerCounter 包裹 handler,它会自动读取 responseWriter 的 statusCode。
otel.SetTracerProvider 必须早于任何 handler 初始化
如果你在 main() 里先注册了 http.HandleFunc,再调用 initTracer(),那第一批请求进来时 otel.Tracer("http") 返回的是 noop tracer —— 它不报错、不丢数据、也不发出去,看起来一切正常,实则 trace 全丢。
- Go 的 init 函数执行顺序不可控,尤其引入第三方 SDK 时容易踩坑;务必确保
initTracer()在http.ListenAndServe之前完成 - 如果用了
gin或echo,别把 tracer 初始化写在某个 middleware 里,它可能被 lazy 加载,错过首批请求 - 验证方式:启动后 curl -s http://localhost:8080/metrics | grep otel_sdk_version,有输出说明 SDK 已生效;无输出则 tracer provider 未设好
用 prometheus.NewHistogram 记录延迟时的桶设置陷阱
直接抄文档里的 prometheus.ExponentialBuckets(0.001, 2, 10) 看似合理,但在高并发微服务下会导致 bucket 过多、cardinality 爆炸,Prometheus 抓取变慢甚至 OOM。
- HTTP 延迟建议用固定分桶:
prometheus.LinearBuckets(0.01, 0.05, 20)(单位秒),覆盖 10ms–1010ms,足够诊断 99% 的慢请求 - 避免对每个 endpoint 单独建 histogram,用 label 区分即可:
httpRequestDuration.WithLabelValues(r.Method, r.URL.Path) - 注意
Observe()调用时机:必须在 writeHeader 之后、body 写入完成前,否则可能统计到未真正响应的时间(比如流式响应中途断开)
Grafana 查不到数据?先查 /metrics 是否含目标指标
很多人改完 Go 代码就跳去 Grafana 刷新 dashboard,结果空白。其实问题常出在最前端:/metrics 根本没暴露对应指标行。
- curl -s http://localhost:8080/metrics | grep http_requests_total —— 如果没输出,说明指标没注册或注册后没被 promhttp.Handler() 拉取
- 检查是否误用
prometheus.NewRegistry()创建了私有 registry,却忘了传给promhttp.HandlerFor(registry, ...) - 确认 handler 注册顺序:若
http.Handle("/metrics", ...)写在http.HandleFunc("/", ...)之后,且后者用了http.DefaultServeMux,那 /metrics 可能被覆盖(Gin/Echo 默认不用 DefaultServeMux,这点反而更安全)
指标对齐、tracer 初始化时机、histogram 分桶粒度、/metrics 端点有效性——这四个点卡住 80% 的可观测性落地问题。它们不难,但错一个,整套链路就变成“看起来在跑,实际没数据”。











