第四篇:《Prometheus 深度实战:指标设计、Exporter 开发与服务发现》

在前三篇文章中,我们建立了可观测性的理论框架,理解了 LGTM 栈的整体架构,并掌握了 OpenTelemetry 的统一插桩标准。但指标监控的"最后一公里"仍然需要深入 Prometheus------它是云原生指标监控的事实标准,也是 LGTM 栈中 Mimir 的数据来源。本文从 Prometheus 的核心架构出发,系统讲解四种指标类型的设计与使用场景、Exporter 开发实战、以及 Kubernetes 服务发现配置,帮你掌握从"指标设计"到"指标采集"的完整技能。

一、Prometheus 核心架构

Prometheus 是一个基于 Pull 模型 的监控系统------它主动从目标服务拉取指标数据,而非等待服务推送。这种设计让服务发现和健康检查变得简单。

核心组件:

Prometheus Server:核心服务,负责抓取、存储和查询指标数据

Exporters:暴露指标的程序(Node Exporter 暴露主机指标,应用自身暴露业务指标)

Alertmanager:处理告警规则的分组、抑制和通知

服务发现(Service Discovery) :动态发现监控目标(Kubernetes、Consul、文件等)

Pull 模型的优势:服务无需感知 Prometheus 的存在;Prometheus 可以通过健康检查判断目标是否可用;便于水平扩展和联邦部署。

二、四种指标类型的设计与使用场景

Prometheus 提供了四种指标类型,每种类型服务于不同的监控目的:

Counter(计数器) :只增不减的累计值。用于统计请求总数、错误总数、处理的任务数等。必须单调递增,不能用于递减或归零的场景。典型用法:http_requests_total。

Gauge(仪表盘) :可增可减的瞬时值。用于测量当前并发数、内存使用量、温度、队列长度等。典型用法:go_goroutines、http_requests_in_flight。

Histogram(直方图) :对观测值进行采样和分桶统计。用于测量请求延迟分布、响应大小等。Histogram 自动生成 _count、_sum 和 _bucket 三个指标。典型用法:http_request_duration_seconds。

Summary(摘要) :类似 Histogram,可计算分位数。与 Histogram 的主要区别在于分位数在客户端计算。建议优先使用 Histogram,因为它更灵活且支持聚合。

指标命名规范:推荐采用 _ 格式。例如 order_service_http_requests_total、api_gateway_request_duration_seconds。

三、自定义 Exporter 开发实战

当需要监控的应用本身不暴露 /metrics 端点时,可以编写自定义 Exporter。Go 语言是 Exporter 开发的首选。

3.1 项目初始化

bash 复制代码
mkdir custom-exporter && cd custom-exporter
go mod init custom-exporter
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

3.2 定义和注册指标

go 复制代码
package main

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    // Counter:累计指标
    ordersCreated = promauto.NewCounter(
        prometheus.CounterOpts{
            Name: "orders_created_total",
            Help: "Total number of orders created",
        },
    )

    // Gauge:瞬时指标
    ordersInFlight = promauto.NewGauge(
        prometheus.GaugeOpts{
            Name: "orders_in_flight",
            Help: "Current number of orders being processed",
        },
    )

    // Histogram:分布指标
    orderDuration = promauto.NewHistogram(
        prometheus.HistogramOpts{
            Name:    "order_duration_seconds",
            Help:    "Order processing duration in seconds",
            Buckets: []float64{0.01, 0.05, 0.1, 0.5, 1, 2, 5},
        },
    )

    // CounterVec:带标签的指标
    ordersByStatus = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "orders_by_status_total",
            Help: "Total number of orders by status",
        },
        []string{"status"},
    )
)

func main() {
    // 暴露 /metrics 端点
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":9090", nil)
}

3.3 采集业务数据并更新指标

go 复制代码
func processOrder() {
    ordersInFlight.Inc()          // 增加并发计数
    defer ordersInFlight.Dec()    // 处理完成后减少

    start := time.Now()
    // 业务逻辑...
    duration := time.Since(start).Seconds()

    ordersCreated.Inc()           // 累计订单数
    orderDuration.Observe(duration) // 记录耗时
    ordersByStatus.WithLabelValues("completed").Inc() // 按状态统计
}

四、Kubernetes 服务发现配置

在 Kubernetes 环境中,Pod 动态创建和销毁,静态配置无法应对这种变化。Prometheus 的 Kubernetes 服务发现 机制可以自动发现集群中的 Pod、Service、Node 等资源。

4.1 基本配置(prometheus.yml)

yaml 复制代码
scrape_configs:
  # 自动发现所有 Pod
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      # 只采集带有 prometheus.io/scrape: "true" 注解的 Pod
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      # 从注解中读取指标路径和端口
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__

4.2 ServiceMonitor(推荐方式)

在 Prometheus Operator 生态中,ServiceMonitor 是更声明式的配置方式:

yaml 复制代码
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: order-service
spec:
  selector:
    matchLabels:
      app: order-service
  endpoints:
  - port: metrics
    path: /metrics
    interval: 15s

ServiceMonitor 将监控目标声明为 Kubernetes 资源,与 Prometheus 的配置解耦,更适合 GitOps 工作流。

五、小结

Prometheus 核心架构:基于 Pull 模型,通过服务发现动态发现目标

四种指标类型:Counter(累计值)、Gauge(瞬时值)、Histogram(分布统计)、Summary(客户端分位数)

指标命名规范:_

Exporter 开发:使用 prometheus/client_golang 定义和注册指标,暴露 /metrics 端点

Kubernetes 服务发现:通过 kubernetes_sd_configs 自动发现 Pod,结合 relabel 进行精细控制

ServiceMonitor:Prometheus Operator 中的声明式监控目标配置

相关推荐
疯子的梦想@2 天前
Prometheus 接入 Alertmanager 与钉钉机器人,附中文模板和完整踩坑记录
机器人·钉钉·prometheus
lbb 小魔仙3 天前
Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程
数据库·人工智能·prometheus·时序数据库
云边有个稻草人4 天前
Prometheus Pushgateway教程:离线任务指标上报、Shell与Python示例、远程访问
开发语言·python·prometheus
广目软件5 天前
HA分布式架构采集节点变更操作手册20261029
运维·服务器·ansible·zabbix·prometheus
闲云自留地8 天前
K8s Service 全解:服务发现、四种类型、会话保持、金丝雀发布一篇通
容器·kubernetes·服务发现
tianyuanwo9 天前
Prometheus 服务部署指南:从架构原理到生产级落地
架构·prometheus
看浪的路人12 天前
第8讲:记忆系统的监控与运维——Prometheus 指标、Grafana 面板与告警体系
运维·grafana·prometheus
爬也要爬着前进13 天前
Prometheus通过Nginx-vts-exporter模块监控nginx服务
运维·nginx·prometheus
Crayon Lin14 天前
Prometheus
prometheus
QYRdata15 天前
机器人3D视觉感知赛道爆发 2026-2032年复合增长率达81.7%
人工智能·3d·机器人·服务发现·恒州博智