强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Prometheus 完全指南 / 11 - Exporter 生态

11 - Exporter 生态

11.1 概述

Exporter 是 Prometheus 生态的核心组件之一,负责将第三方系统的指标转换为 Prometheus 可抓取的格式(/metrics 端点)。

工作原理

┌──────────┐        ┌──────────────┐        ┌──────────────┐
│ 第三方系统 │◄──────►│  Exporter    │◄──────►│  Prometheus  │
│ (MySQL等) │  查询   │  /metrics    │  抓取   │  Server      │
└──────────┘        └──────────────┘        └──────────────┘

1. Exporter 连接第三方系统
2. 查询/收集指标数据
3. 转换为 Prometheus 格式
4. 暴露 /metrics 端点
5. Prometheus 定期抓取

常用 Exporter

Exporter用途默认端口
Node Exporter系统/硬件指标9100
MySQL ExporterMySQL 数据库9104
Redis ExporterRedis 缓存9121
MongoDB ExporterMongoDB9216
Blackbox Exporter黑盒探针9115
Nginx ExporterNginx9113
Kafka ExporterKafka9308
Elasticsearch ExporterElasticsearch9114
RabbitMQ ExporterRabbitMQ9419
PostgreSQL ExporterPostgreSQL9187

11.2 Node Exporter

Node Exporter 是最基础也是最常用的 Exporter,用于收集系统级指标。

安装

# 二进制安装
NODE_EXPORTER_VERSION="1.7.0"
wget https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xvfz node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
sudo cp node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter /usr/local/bin/

# Docker
docker run -d \
  --name=node-exporter \
  --net=host \
  --pid=host \
  -v "/:/host:ro,rslave" \
  prom/node-exporter:v1.7.0 \
  --path.rootfs=/host

Systemd 服务

# /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/bin/node_exporter \
  --collector.systemd \
  --collector.processes \
  --web.listen-address=:9100
Restart=always

[Install]
WantedBy=multi-user.target

主要指标

指标说明
node_cpu_seconds_totalCPU 使用时间
node_memory_MemTotal_bytes总内存
node_memory_MemAvailable_bytes可用内存
node_filesystem_size_bytes文件系统总大小
node_filesystem_avail_bytes文件系统可用空间
node_network_receive_bytes_total网络接收字节数
node_disk_io_time_seconds_total磁盘 IO 时间
node_load1/5/15系统负载
node_boot_time_seconds系统启动时间
node_time_seconds当前时间

常用 Collector

Collector默认说明
cpuCPU 指标
diskstats磁盘统计
filesystem文件系统
loadavg系统负载
meminfo内存信息
netdev网络设备
systemdsystemd 服务状态
processes进程信息
hwmon硬件传感器
# 启用特定 collector
node_exporter \
  --collector.systemd \
  --collector.processes \
  --no-collector.wifi \
  --no-collector.infiniband

11.3 MySQL Exporter

安装与配置

# 安装
MYSQL_EXPORTER_VERSION="0.15.1"
wget https://github.com/prometheus/mysqld_exporter/releases/download/v${MYSQL_EXPORTER_VERSION}/mysqld_exporter-${MYSQL_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xvfz mysqld_exporter-${MYSQL_EXPORTER_VERSION}.linux-amd64.tar.gz
sudo cp mysqld_exporter-${MYSQL_EXPORTER_VERSION}.linux-amd64/mysqld_exporter /usr/local/bin/

创建 MySQL 用户

-- 创建监控专用用户
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password';

-- 授予权限
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';

FLUSH PRIVILEGES;

配置文件

# /etc/.mysqld_exporter.cnf
[client]
user=exporter
password=password
host=localhost
port=3306

启动

mysqld_exporter \
  --config.my-cnf=/etc/.mysqld_exporter.cnf \
  --collect.info_schema.processlist \
  --collect.info_schema.innodb_metrics \
  --collect.global_status \
  --collect.global_variables \
  --collect.slave_status \
  --collect.engine_innodb_status

主要指标

指标说明
mysql_upMySQL 是否可达
mysql_global_status_threads_connected当前连接数
mysql_global_status_threads_running活跃线程数
mysql_global_status_queries查询总数
mysql_global_status_slow_queries慢查询总数
mysql_global_status_questions问题总数
mysql_global_status_innodb_buffer_pool_readsInnoDB 缓冲池读取
mysql_info_schema_processlist_count进程列表

11.4 Redis Exporter

安装与启动

# 安装
REDIS_EXPORTER_VERSION="1.58.0"
wget https://github.com/oliver006/redis_exporter/releases/download/v${REDIS_EXPORTER_VERSION}/redis_exporter-v${REDIS_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xvfz redis_exporter-v${REDIS_EXPORTER_VERSION}.linux-amd64.tar.gz
sudo cp redis_exporter /usr/local/bin/

# 启动
redis_exporter \
  --redis.addr=redis://localhost:6379 \
  --redis.password=password \
  --web.listen-address=:9121

# Docker
docker run -d \
  --name=redis-exporter \
  -p 9121:9121 \
  oliver006/redis_exporter:v1.58.0 \
  --redis.addr=redis://redis:6379

主要指标

指标说明
redis_upRedis 是否可达
redis_connected_clients连接客户端数
redis_used_memory_bytes使用内存
redis_memory_max_bytes最大内存限制
redis_commands_processed_total命令处理总数
redis_keyspace_hits_total缓存命中
redis_keyspace_misses_total缓存未命中
redis_connected_slaves从节点数

常用查询

# 缓存命中率
redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)

# 内存使用率
redis_used_memory_bytes / redis_memory_max_bytes

# 每秒命令处理数
rate(redis_commands_processed_total[5m])

11.5 Blackbox Exporter

Blackbox Exporter 通过 HTTP、TCP、ICMP、DNS 等协议探测目标的可用性。

配置文件

# /etc/blackbox_exporter/config.yml
modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
      valid_status_codes: [200, 301, 302]
      method: GET
      follow_redirects: true
      preferred_ip_protocol: "ip4"
      tls_config:
        insecure_skip_verify: false

  http_post_2xx:
    prober: http
    http:
      method: POST
      valid_status_codes: [200, 201]

  tcp_connect:
    prober: tcp
    timeout: 5s

  icmp:
    prober: icmp
    timeout: 5s

  dns_resolve:
    prober: dns
    dns:
      query_name: "example.com"
      query_type: "A"
      valid_rcodes: ["NOERROR"]

启动

blackbox_exporter \
  --config.file=/etc/blackbox_exporter/config.yml \
  --web.listen-address=:9115

Prometheus 配置

scrape_configs:
  # HTTP 探测
  - job_name: 'blackbox-http'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
          - https://example.com
          - https://api.example.com/health
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

  # ICMP 探测
  - job_name: 'blackbox-icmp'
    metrics_path: /probe
    params:
      module: [icmp]
    static_configs:
      - targets:
          - 10.0.0.1
          - 10.0.0.2
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

  # TCP 探测
  - job_name: 'blackbox-tcp'
    metrics_path: /probe
    params:
      module: [tcp_connect]
    static_configs:
      - targets:
          - mysql:3306
          - redis:6379
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

主要指标

指标说明
probe_success探测是否成功 (1/0)
probe_duration_seconds探测耗时
probe_http_status_codeHTTP 状态码
probe_http_duration_secondsHTTP 各阶段耗时
probe_dns_lookup_time_secondsDNS 解析时间
probe_icmp_duration_secondsICMP 耗时

11.6 自定义 Exporter

Go 实现

package main

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

var (
    // 定义指标
    ordersTotal = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Namespace: "business",
            Subsystem: "orders",
            Name:      "created_total",
            Help:      "Total number of orders created",
        },
        []string{"channel", "status"},
    )

    orderAmount = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Namespace: "business",
            Subsystem: "orders",
            Name:      "amount_cents",
            Help:      "Order amount in cents",
            Buckets:   []float64{100, 500, 1000, 5000, 10000, 50000, 100000},
        },
        []string{"channel"},
    )

    queueLength = prometheus.NewGaugeVec(
        prometheus.GaugeOpts{
            Namespace: "business",
            Subsystem: "orders",
            Name:      "queue_length",
            Help:      "Current order processing queue length",
        },
        []string{"queue"},
    )
)

func init() {
    prometheus.MustRegister(ordersTotal, orderAmount, queueLength)
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":9200", nil)
}

Python 实现

from prometheus_client import start_http_server, Counter, Gauge, Histogram
import time
import psutil

# 定义指标
CPU_TEMP = Gauge('hardware_cpu_temperature_celsius', 'CPU temperature')
DISK_IO = Counter('hardware_disk_reads_total', 'Total disk reads', ['device'])
REQUEST_LATENCY = Histogram(
    'custom_request_duration_seconds',
    'Request latency',
    buckets=[0.01, 0.05, 0.1, 0.5, 1, 5]
)

def collect_metrics():
    """定期采集指标"""
    while True:
        # CPU 温度
        temps = psutil.sensors_temperatures()
        if 'coretemp' in temps:
            CPU_TEMP.set(temps['coretemp'][0].current)
        
        # 磁盘 IO
        io = psutil.disk_io_counters()
        DISK_IO.labels(device='sda')._value.set(io.read_count)
        
        time.sleep(15)

if __name__ == '__main__':
    start_http_server(9200)
    collect_metrics()

11.7 Exporter 最佳实践

实践说明
使用官方 Exporter优先选择 Prometheus 官方维护的 Exporter
合理设置采集间隔Exporter 系统的采集间隔应与 Prometheus 抓取间隔匹配
限制标签基数避免 Exporter 产生高基数标签
独立部署Exporter 应与被监控系统部署在同一主机
资源限制为 Exporter 设置 CPU/内存限制
超时配置设置合理的抓取超时

11.8 本章小结

Exporter用途默认端口
Node Exporter系统指标9100
MySQL ExporterMySQL9104
Redis ExporterRedis9121
Blackbox Exporter探针9115
自定义 Exporter业务指标自定义

扩展阅读


上一章10 - 服务发现 下一章12 - Pushgateway