第四章:Exporter 数据采集¶
什么是 Exporter?¶
Exporter 是 Prometheus 生态中的数据导出器,负责将应用或系统的指标转换为 Prometheus 可识别的格式。
常用 Exporter¶
| Exporter | 用途 | 默认端口 |
|---|---|---|
| node_exporter | 主机监控 | 9100 |
| mysqld_exporter | MySQL 监控 | 9104 |
| redis_exporter | Redis 监控 | 9121 |
| nginx_exporter | Nginx 监控 | 9113 |
| blackbox_exporter | 黑盒监控 | 9115 |
| cadvisor | 容器监控 | 8080 |
| jmx_exporter | Java 应用监控 | 9404 |
Node Exporter¶
安装¶
# 下载
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
# 解压
tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
cd node_exporter-1.7.0.linux-amd64
# 启动
./node_exporter
# systemd 服务
cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
After=network.target
[Service]
Type=simple
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable node_exporter
systemctl start node_exporter
Docker 部署¶
docker run -d \
--name node-exporter \
-p 9100:9100 \
-v /proc:/host/proc:ro \
-v /sys:/host/sys:ro \
-v /:/rootfs:ro \
prom/node-exporter \
--path.procfs=/host/proc \
--path.sysfs=/host/sys \
--path.rootfs=/rootfs
常用指标¶
# CPU 使用率
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 内存使用率
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# 磁盘使用率
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100
# 网络流量
rate(node_network_receive_bytes_total[5m])
rate(node_network_transmit_bytes_total[5m])
# 系统负载
node_load1
node_load5
node_load15
# 文件描述符
node_filefd_allocated / node_filefd_maximum * 100
MySQL Exporter¶
安装¶
# 创建监控用户
mysql> CREATE USER 'exporter'@'%' IDENTIFIED BY 'password';
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
# Docker 部署
docker run -d \
--name mysqld-exporter \
-p 9104:9104 \
-e DATA_SOURCE_NAME="exporter:password@(mysql:3306)/" \
prom/mysqld-exporter
常用指标¶
# MySQL 连接数
mysql_global_status_threads_connected
# MySQL 慢查询
mysql_global_status_slow_queries
# MySQL 查询速率
rate(mysql_global_status_queries[5m])
# MySQL 连接使用率
mysql_global_status_threads_connected / mysql_global_variables_max_connections * 100
# InnoDB 缓冲池使用率
mysql_global_status_innodb_buffer_pool_pages_data / mysql_global_status_innodb_buffer_pool_pages_total * 100
Redis Exporter¶
安装¶
# Docker 部署
docker run -d \
--name redis-exporter \
-p 9121:9121 \
-e REDIS_ADDR="redis://redis:6379" \
-e REDIS_PASSWORD="password" \
oliver006/redis_exporter
常用指标¶
# Redis 连接数
redis_connected_clients
# Redis 内存使用
redis_memory_used_bytes
# Redis 键数量
redis_db_keys
# Redis 命令速率
rate(redis_commands_total[5m])
# Redis 缓存命中率
rate(redis_keyspace_hits_total[5m]) / (rate(redis_keyspace_hits_total[5m]) + rate(redis_keyspace_misses_total[5m])) * 100
Nginx Exporter¶
配置 Nginx¶
# nginx.conf
server {
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
安装 Exporter¶
# Docker 部署
docker run -d \
--name nginx-exporter \
-p 9113:9113 \
-e NGINX_STATUS_URL="http://nginx:80/nginx_status" \
nginx/nginx-prometheus-exporter
常用指标¶
# 请求数
nginx_http_requests_total
# 连接数
nginx_connections_active
nginx_connections_reading
nginx_connections_writing
nginx_connections_waiting
# 请求速率
rate(nginx_http_requests_total[5m])
Blackbox Exporter¶
安装¶
# Docker 部署
docker run -d \
--name blackbox-exporter \
-p 9115:9115 \
-v $(pwd)/blackbox.yml:/etc/blackbox_exporter/config.yml \
prom/blackbox-exporter
配置文件¶
# blackbox.yml
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2"]
valid_status_codes: [200]
method: GET
follow_redirects: true
http_post_2xx:
prober: http
timeout: 5s
http:
method: POST
headers:
Content-Type: application/json
body: '{"status":"ok"}'
tcp_connect:
prober: tcp
timeout: 5s
icmp:
prober: icmp
timeout: 5s
dns:
prober: dns
timeout: 5s
dns:
transport_protocol: "udp"
query_name: "example.com"
query_type: "A"
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-exporter:9115
# ICMP 探测
- job_name: 'blackbox-icmp'
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets:
- 192.168.1.1
- 192.168.1.2
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
常用指标¶
# 探测成功
probe_success
# 探测延迟
probe_duration_seconds
# HTTP 状态码
probe_http_status_code
# SSL 证书过期时间
probe_ssl_earliest_cert_expiry
cAdvisor(容器监控)¶
安装¶
# Docker 部署
docker run -d \
--name cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
google/cadvisor
Docker Compose¶
version: '3.8'
services:
cadvisor:
image: google/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
restart: unless-stopped
常用指标¶
# 容器 CPU 使用率
rate(container_cpu_usage_seconds_total[5m]) * 100
# 容器内存使用
container_memory_usage_bytes
# 容器网络流量
rate(container_network_receive_bytes_total[5m])
rate(container_network_transmit_bytes_total[5m])
# 容器文件系统使用
container_fs_usage_bytes
自定义 Exporter¶
Python 示例¶
#!/usr/bin/env python3
from prometheus_client import Counter, Gauge, Histogram, start_server
import random
import time
# 定义指标
REQUEST_COUNT = Counter('app_requests_total', 'Total requests', ['method', 'endpoint'])
REQUEST_LATENCY = Histogram('app_request_latency_seconds', 'Request latency', ['endpoint'])
ACTIVE_CONNECTIONS = Gauge('app_active_connections', 'Active connections')
@REQUEST_LATENCY.time()
def handle_request(endpoint):
REQUEST_COUNT.labels(method='GET', endpoint=endpoint).inc()
time.sleep(random.random() * 0.1)
if __name__ == '__main__':
start_server(8000)
while True:
ACTIVE_CONNECTIONS.set(random.randint(1, 100))
handle_request('/api/users')
time.sleep(1)
Go 示例¶
package main
import (
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "app_requests_total",
Help: "Total number of requests",
},
[]string{"method", "endpoint"},
)
requestLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "app_request_latency_seconds",
Help: "Request latency in seconds",
Buckets: prometheus.DefBuckets,
},
[]string{"endpoint"},
)
)
func init() {
prometheus.MustRegister(requestsTotal)
prometheus.MustRegister(requestLatency)
}
func handler(w http.ResponseWriter, r *http.Request) {
start := time.Now()
requestsTotal.WithLabelValues(r.Method, r.URL.Path).Inc()
time.Sleep(time.Millisecond * 100)
requestLatency.WithLabelValues(r.URL.Path).Observe(time.Since(start).Seconds())
w.WriteHeader(http.StatusOK)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
小结¶
本章学习了:
- ✅ Exporter 概念和类型
- ✅ Node Exporter 配置
- ✅ 数据库 Exporter 配置
- ✅ Blackbox Exporter 配置
- ✅ 容器监控配置
- ✅ 自定义 Exporter 开发
下一章¶
第五章:Grafana 可视化 - 学习 Grafana 可视化配置。