第四篇:《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 中的声明式监控目标配置

相关推荐
刘某的Cloud2 小时前
k8s部署prometheus架构规则
linux·运维·kubernetes·prometheus·监控
LlmCraft|大模型工程实践4 小时前
12. Docker 日志管理与监控:ELK 日志收集 + Prometheus 性能监控
elk·docker·prometheus
格桑阿sir6 小时前
Kubernetes服务发现机制(二):Service、Endpoint、EndpointSlice
kubernetes·服务发现·负载均衡·service·endpoint·lb·endpointslice
DevOps老兵14 小时前
AI Infra实战02:GPU监控实战,用DCGM+Prometheus+Grafana看清每一张卡
人工智能·grafana·prometheus·ai infra·gpu监控·dcgm
heimeiyingwang16 小时前
【Prometheus·入门篇】数据模型:Metric 类型、标签与时间序列
prometheus
heimeiyingwang1 天前
【Prometheus·部署篇】配置详解:scrape_config、relabeling 与服务发现
prometheus
heimeiyingwang4 天前
【Prometheus·入门篇】Prometheus 是什么:从 Nagios 到云原生监控的演进
prometheus
秋风点枝6 天前
第一篇:认识 Prometheus —— 云原生监控的基础
云原生·prometheus
名字还没想好☜6 天前
Prometheus 告警实战:写 alerting rules、用 Alertmanager 做路由分组与抑制
运维·前端·javascript·docker·kubernetes·prometheus