必须显式调用 prometheus.MustRegister() 注册指标否则 /metrics 中不可见自定义注册器需用 promhttp.HandlerFor()标签名全小写下划线避免高基数HPA 需 rate() 而非原始 CounterseriesQuery 必须与代码中 Name 完全一致直方图需按真实延迟设 Buckets。必须显式注册否则 /metrics 里根本看不到你的指标很多人跑通了 http.Handle(/metrics, promhttp.Handler())一访问 http://localhost:8080/metrics 却只看到 go_* 和 process_*自己的 http_requests_total 消失得无影无踪——这不是 Prometheus 没抓到是你压根没把它“交出去”。promhttp.Handler() 只暴露注册在默认注册器上的指标而 Go SDK 创建的指标对象比如 prometheus.NewCounterVec只是个空壳不调 prometheus.MustRegister() 就等于没申报。别在 init() 里定义指标又忘了注册更糟的是在多个包里 import 同一个 metrics 包导致重复 MustRegister直接 panicduplicate metrics collector如果用了自定义注册器比如 reg : prometheus.NewRegistry()就一定用 promhttp.HandlerFor(reg, ...)而不是默认的 promhttp.Handler()标签名必须全小写、下划线分隔、不以数字开头值里别塞 user_id12345 这种高基数字段否则 Prometheus 存储会爆炸Counter 不能直接给 HPA 用rate() 才是真实速率你在 Go 里定义了 my_app_http_requests_totalPrometheus 能采到但一旦想让 Kubernetes HPA 基于它自动扩缩容就会发现 HPA 一直不触发——因为 HPA 需要的是“每秒请求数”而 Counter 是累计值。Adapter 规则里若写 metricQuery: my_app_http_requests_total查出来的是 127489 这种不断增长的大整数HPA 完全无法理解。Adapter 的 rules.yaml 中metricQuery 必须包装函数比如 rate(my_app_http_requests_total[2m])seriesQuery 必须和你 Go 代码中定义的 Name 字段**完全一致**包括大小写和下划线少一个字符 Adapter 就查不到resources 字段不能空着必须指定 template: pod{{.Resource}} 或 overrides否则 Adapter 启动直接报错resource mapping not defined别手写 /metrics handler也别用框架“套壳”有人为了加鉴权或日志在 promhttp.Handler() 外再包一层 http.HandleFunc或者在 Gin/Echo 里写 router.GET(/metrics, gin.WrapH(promhttp.Handler()))——这会导致 Accept 头协商失败、gzip 不生效、甚至返回 406 Not Acceptable。Prometheus 的文本格式有版本协商机制如 Accept: application/openmetrics-text; version1.0.0手写的 handler 根本不处理。坚持用 promhttp.Handler() 或 promhttp.HandlerFor(reg, opts)这是唯一能正确响应各种 Content-Type 和错误码的方式需要 Basic Auth在 mux 层拦截比如 mux.Handle(/metrics, withAuth(promhttp.Handler()))不要侵入 Handler 内部逻辑别把 /metrics 挂在带参数的路由下如 /api/v1/:id/metricsAdapter 和 Prometheus 的 scrape 都依赖固定路径匹配直方图 Buckets 设错P99 就永远不准HTTP 延迟监控最常用 prometheus.NewHistogramVec但很多人直接用默认 DefBuckets最大才 10 秒结果线上 P99 显示是 10s实际接口早超 30s 了——因为所有 ≥10s 的样本全被塞进最后一个桶分位数计算彻底失真。 Tellers AI Tellers是一款自动视频编辑工具可以将文本、文章或故事转换为视频。