Prometheus+Grafana Exporter的使用
3665 字
18 分钟
Prometheus+Grafana Exporter的使用
1. Exporter 介绍
Exporter 是将各种被监控的服务(如:MySQL,Redis,Kafka,Nginx等)的各种指标数据装换为 Prometheus 可以解析的结构化数据的中间件。它的核心任务是将不同来源、不同格式的监控数据,统一“翻译”成 Prometheus 能够识别和抓取的格式。
为什么需要 Exporter?
这主要是因为 Prometheus 采用 Pull(拉取)模型来获取数据。这意味着它需要被监控对象提供一个标准化的 HTTP 接口(通常是
/metrics)来暴露数据。然而,并非所有系统都原生支持这种格式。因此,Exporter 就扮演了中间人的角色:
- 对于无法直接提供数据的系统:比如 Linux 操作系统、MySQL、Redis 等,它们自身没有
/metrics接口,所以需要借助 Exporter 来采集和转化数据。- 对于已原生支持的系统:像 Kubernetes、etcd 这类云原生组件以及 hertz、go-zero 这类框架,自身就集成了
/metrics接口,它们本身就可以被视为一个内置的 Exporter。
2. 常见的 Exporter
Prometheus 社区维护了丰富的 Exporter,几乎覆盖了所有主流技术栈。以下是一些最常用的:
| 类别 | Exporter 名称 | 主要监控对象 | 默认端口 |
|---|---|---|---|
| 基础设施 | Node Exporter | 主机硬件和操作系统(CPU, 内存, 磁盘, 网络等) | 9100 |
| Windows Exporter | Windows 操作系统 | - | |
| SNMP Exporter | 网络设备(支持SNMP协议的交换机、路由器等,甚至是PDU) | - | |
| 数据库 | MySQL Exporter | MySQL 数据库性能指标 | 9104 |
| Redis Exporter | Redis 缓存数据库指标 | - | |
| PostgreSQL Exporter | PostgreSQL 数据库 | - | |
| MongoDB Exporter | MongoDB 数据库 | - | |
| 中间件 | JMX Exporter | Java 应用程序(通过 JMX) | - |
| Kafka Exporter | Apache Kafka 消息队列 | - | |
| RabbitMQ Exporter | RabbitMQ 消息队列 | - | |
| Nginx Exporter | Nginx Web 服务器 | - | |
| 可用性 | Blackbox Exporter | 探测 HTTP/HTTPS/DNS/TCP 等网络端点 | - |
| 硬件 | DCGM Exporter | NVIDIA GPU 指标 | 9400 |
3. 几种 Exporter 的安装
3.1 Node Exporter
这里使用
docker-compose
- docker-compose.yaml
services: node-exporter: image: prom/node-exporter:latest container_name: node-exporter restart: unless-stopped ports: - "9100:9100" # 可选:把宿主机的9100也映射出来,方便直接访问 volumes: - /proc:/host/proc:ro # 挂载宿主机 /proc(只读) - /sys:/host/sys:ro # 挂载宿主机 /sys(只读) - /:/rootfs:ro # 挂载宿主机根文件系统(只读) command: - '--path.procfs=/host/proc' - '--path.sysfs=/host/sys' - '--path.rootfs=/rootfs' - '--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+)($|/)' # 排除无用挂载点- 覆盖指标
| 监控类别 | 关键指标示例 | 用途说明 |
|---|---|---|
| CPU性能 | node_cpu_seconds_total (CPU时间) node_load1 (1分钟负载) | 监控CPU使用率、系统负载、上下文切换等 |
| 内存 | node_memory_MemTotal_bytes (总内存) node_memory_MemAvailable_bytes (可用内存) | 监控物理内存、交换内存的使用情况和可用容量 |
| 磁盘存储 | node_filesystem_size_bytes (总容量) node_filesystem_avail_bytes (可用空间) node_filesystem_readonly (只读状态) | 监控文件系统的容量、使用率及挂载状态 |
| 磁盘I/O | node_disk_reads_completed_total (读取次数) node_disk_written_bytes_total (写入字节数) | 监控磁盘读写吞吐量、IOPS及I/O操作耗时 |
| 网络 | node_network_receive_bytes_total (接收字节数) node_network_transmit_bytes_total (发送字节数) node_network_receive_errs_total (接收错误数) | 监控网络流量、数据包收发、错误与丢包情况 |
| 系统信息 | node_time_seconds (系统时间) node_boot_time_seconds (启动时间) node_os_version (操作系统版本) | 获取系统的基础信息和运行时间 |
| 进程/文件句柄 | node_processes_state (进程状态分布) node_filefd_allocated (已分配文件描述符) | 监控系统进程总数以及文件描述符的使用情况 |
| 硬件/传感器 | node_hwmon_temp_celsius (CPU温度) node_power_supply_voltage (电压) | 监控硬件温度、风扇转速和电源电压等 |
- 效果

DashBoard ID:1860
3.2 cAdvisor
这里使用
docker-compose
- docker-compose.yaml
services: cadvisor: # 使用官方最新镜像(gcr.io 有时需代理,可用 docker.io 的同步镜像) image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/cadvisor/cadvisor:v0.55.1 container_name: cadvisor ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro # 关键:显式挂载 cgroup,v2 下必须 - /sys/fs/cgroup:/sys/fs/cgroup:ro # 给予必要权限(比 privileged 更安全) cap_add: - SYS_ADMIN restart: unless-stopped # 可选:额外启用调试日志(初次排查用) # environment: # - CADVISOR_DEBUG=1- 覆盖指标
| 监控类别 | 关键指标示例 | 用途说明 |
|---|---|---|
| CPU 使用 | container_cpu_usage_seconds_total | 容器累计消耗的 CPU 时间(秒),可计算使用率 |
| CPU 限制 | container_spec_cpu_quota / container_spec_cpu_period | 容器的 CPU 配额与周期,用于计算 CPU 上限 |
| CPU 调度 | container_cpu_cfs_throttled_seconds_total | 容器因超出 CPU 限额而被限流的累计时间 |
| CPU 核数 | container_spec_cpu_shares | 容器的 CPU 权重(相对优先级) |
| 内存用量 | container_memory_working_set_bytes | 容器当前工作集内存(实际活跃使用量,更准确) |
| 内存总量 | container_spec_memory_limit_bytes | 容器的内存限制上限(0 表示无限制) |
| 内存详情 | container_memory_rss_bytes / container_memory_cache_bytes | RSS(常驻内存)和文件缓存占用量 |
| 交换内存 | container_memory_swap_limit_bytes / container_memory_swap_usage_bytes | 交换内存的限制和当前使用量 |
| OOM 事件 | container_oom_events_total | 容器发生内存溢出(Out Of Memory)的累计次数 |
| 网络接收 | container_network_receive_bytes_total | 容器网络接收的累计字节数(流量) |
| 网络发送 | container_network_transmit_bytes_total | 容器网络发送的累计字节数(流量) |
| 网络数据包 | container_network_receive_packets_total / container_network_transmit_packets_total | 容器网络接收/发送的累计数据包数 |
| 网络丢包 | container_network_receive_packets_dropped_total / container_network_transmit_packets_dropped_total | 容器网络接收/发送时丢弃的累计数据包数 |
| 网络错误 | container_network_receive_errors_total / container_network_transmit_errors_total | 容器网络接收/发送时发生的累计错误数 |
| 存储用量 | container_fs_usage_bytes | 容器在文件系统上的存储空间占用量 |
| 存储总量 | container_fs_limit_bytes | 容器的存储限制总量 |
| 存储读取 | container_fs_reads_bytes_total | 容器从磁盘读取的累计字节数 |
| 存储写入 | container_fs_writes_bytes_total | 容器写入磁盘的累计字节数 |
| 存储 IO 操作 | container_fs_reads_total / container_fs_writes_total | 容器读/写磁盘的累计 IO 操作次数 |
| 存储 I/O 耗时 | container_fs_io_time_seconds_total | 容器在文件系统上执行 I/O 操作的累计耗时 |
| 容器元数据 | container_start_time_seconds | 容器的启动时间戳 |
| 容器状态 | container_state | 容器的当前状态(running、waiting、terminated 等) |
| 进程/线程 | container_processes / container_threads | 容器内部的进程数和线程数 |
| 文件描述符 | container_file_descriptors | 容器当前打开的文件描述符数量 |
| 标签信息 | container_label_* | 容器的各类标签(如镜像名、Pod 名称等) |
- 效果

DashBoard ID:14282
3.3 PostgreSQL Exporter
这里使用
docker-compose
- docker-compose.yaml
services: postgres-exporter: image: docker.1ms.run/prometheuscommunity/postgres-exporter:latest container_name: postgres-exporter ports: - "9187:9187" # 将宿主机的9187端口映射到容器 environment: DATA_SOURCE_URI: "host.your.postgresql:5432/your_database?sslmode=disable" DATA_SOURCE_USER: "exporter" DATA_SOURCE_PASS: "exporter-password" PG_EXPORTER_COLLECTION_TIMEOUT: "2m" # 可选,采集超时时间 networks: - monitoring-network
networks: monitoring-network: external: true- 启用额外的采集器:如果需要采集更详细的指标(如 pg_stat_statements、长事务等),可以在
docker-compose.yml中追加命令参数
command: - "--collector.stat_statements" - "--collector.long_running_transactions"- 在 Postgresql 内创建 Exporter 的专用账号
-- 创建用户,并限制其最大连接数以防资源耗尽CREATE USER exporter WITH PASSWORD 'exporter-password' CONNECTION LIMIT 3;-- 授予监控所需的权限GRANT CONNECT ON DATABASE your_database TO exporter;-- 在 PostgreSQL 10+ 中,pg_monitor 角色提供了所需的只读权限GRANT pg_monitor TO exporter;- 覆盖指标
| 监控类别 | 关键指标示例 | 用途说明 |
|---|---|---|
| 数据库与连接 | pg_database_size_bytes | 每个数据库的磁盘占用空间。 |
pg_database_connection_limit | 每个数据库的最大连接数限制。 | |
pg_stat_database_numbackends | 当前连接到每个数据库的后端进程数。 | |
| 事务与查询 | pg_stat_database_xact_commit | 已提交的事务总数。 |
pg_stat_database_xact_rollback | 已回滚的事务总数。 | |
pg_stat_database_tup_returned | 查询返回的行数。 | |
| 缓存与I/O | pg_stat_database_blks_hit | 缓冲区缓存命中次数。 |
pg_stat_database_blks_read | 从磁盘读取的块数。 | |
pg_stat_database_temp_bytes | 写入临时文件的总数据量。 | |
| 复制与高可用 | pg_stat_replication | 监控复制状态、延迟等(需启用对应collector)。 |
| 锁 | pg_locks | 提供数据库锁的详细信息(需启用对应collector)。 |
指标名称通常以
pg_为前缀,Exporter 支持通过 20 多个内置采集器(Collectors) 来按需获取不同维度的数据。
- 效果

DashBoard ID:9628
3.4 Redis Exporter
这里使用
docker-compose
- docker-compose.yaml
services: redis-exporter: image: docker.1ms.run/oliver006/redis_exporter:latest container_name: redis-exporter ports: - "9121:9121" environment: - REDIS_ADDR=redis://your-redis-host:6379 # 替换为你的Redis地址 - REDIS_PASSWORD=your_redis_password # 直接设置密码 restart: always- 覆盖指标
| 指标类别 | 关键指标示例 | 用途说明 |
|---|---|---|
| 基础与状态 | redis_up | 实例存活状态,1 表示可用,0 表示不可用,是核心告警指标。 |
redis_uptime_in_seconds | Redis 实例已运行的秒数,可据此判断是否发生过重启。 | |
redis_instance_info | 提供实例的元数据信息,如 role(master/slave)。 | |
| 连接与客户端 | redis_connected_clients | 当前连接的客户端数量。 |
redis_config_maxclients | 配置的最大连接数,可与 connected_clients 结合计算连接使用率。 | |
redis_rejected_connections_total | 因超过最大连接数而被拒绝的连接总数。 | |
redis_blocked_clients | 正在等待阻塞命令(如 BLPOP)的客户端数量。 | |
| 内存 | redis_memory_used_bytes | Redis 当前使用的总内存(字节)。 |
redis_memory_max_bytes | Redis 可用的最大内存(字节),0 表示无限制。 | |
redis_memory_fragmentation_ratio | 内存碎片率。该值持续过高(>1.5)可能表明内存碎片严重。 | |
redis_memory_used_rss_bytes | 操作系统实际分配给 Redis 的物理内存(RSS)。 | |
| 命令与吞吐量 | redis_commands_total | 累计处理的命令总数,可使用 rate() 函数计算 QPS。 |
redis_commands_duration_seconds_total | 处理命令累计消耗的总时间,用于计算命令平均延迟。 | |
redis_connections_received_total | 累计接收的连接总数。 | |
redis_net_input_bytes_total | 网络入站累计字节数。 | |
| 键空间与缓存效率 | redis_keys_total{db="x"} | 每个数据库中的键总数。 |
redis_expired_keys_total | 累计过期并被删除的键总数。 | |
redis_evicted_keys_total | 因内存达到 maxmemory 限制而被驱逐的键总数。 | |
redis_keyspace_hits_total | 键查找成功的总次数。 | |
redis_keyspace_misses_total | 键查找失败的总次数。 | |
| (未直接提供) | 缓存命中率可使用 hits / (hits + misses) 计算。 | |
| 持久化 (RDB/AOF) | redis_last_save_time_seconds | 最后一次成功执行 RDB 持久化的时间戳。 |
redis_last_save_changes_total | 自上次 RDB 保存以来发生的更改次数。 | |
redis_aof_current_size | 当前 AOF 文件的大小。 | |
redis_aof_last_cow_size | 最后一次 AOF 重写时的写时复制(Copy-on-Write)内存大小。 | |
| 主从复制 | redis_connected_slaves | 已连接的从库(replica)数量。 |
redis_master_link_up | 从库与主库的连接状态,1 表示连接正常。 | |
redis_slave_replication_lag | 主从复制延迟。 | |
| 集群 | redis_cluster_known_nodes | 集群中已知的节点总数。 |
redis_cluster_slots_fail | 处于故障状态的槽(slot)数量。 | |
| CPU | redis_cpu_user_seconds_total | Redis 累计消耗的用户态 CPU 时间。 |
redis_cpu_sys_seconds_total | Redis 累计消耗的系统态 CPU 时间。 |
- 效果

DashBoard ID:763
4. 自定义 Exporter
这里以 Golang 为例子
- 下载需要使用的包
go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttp- 最小示例
package main
import ( "math/rand" "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 1. 定义一个 Gauge 指标 temp := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "temperature_celsius", Help: "Current temperature in Celsius.", }) prometheus.MustRegister(temp)
// 2. 后台更新指标值 go func() { for { temp.Set(20 + rand.Float64()*10) // 随机 20~30 度 time.Sleep(5 * time.Second) } }()
// 3. 启动 HTTP 服务,暴露 /metrics http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}- 支持指标类型总览
| 类型 | 特点 | 典型用途 | 重要方法 |
|---|---|---|---|
| Counter | 只增不减的累计值(重启后归零) | 请求总数、错误总数、处理过的消息数 | Inc(), Add(float64) |
| Gauge | 可增可减的瞬时值 | 当前温度、内存使用量、活跃连接数、队列长度 | Set(float64), Inc(), Dec(), Add(float64), Sub(float64) |
| Histogram | 对观测值进行采样并统计分位数(桶) | 请求耗时、响应大小(用于计算 P50/P90/P99) | Observe(float64) |
| Summary | 直接计算滑动时间窗口内的分位数(服务端计算) | 请求耗时(需要精确分位数,但客户端开销较大) | Observe(float64) |
- 支持的指标类型详细介绍
- Counter(计数器)
- 语义:单调递增的累计值,通常用来统计事件发生的次数(例如请求总数、错误总数)。
- 特点:不能减少,除非进程重启(重启后归零)。适合用
rate()函数计算速率。 - 方法:
Inc():增加 1。Add(float64):增加指定的数值(可以是小数)。
- 标签注意:通常按状态、方法等维度划分,但要避免高基数标签(如用户ID)。
- 典型场景:HTTP 请求总数、消息队列消费总数。
- Gauge(仪表盘)
- 语义:可任意变化的数值,代表某个时刻的状态。
- 特点:可增可减,适合展示当前值,如温度、内存、连接数。
- 方法:
Set(float64):直接设置为某个值。Inc()/Dec():增减 1。Add(float64)/Sub(float64):增减指定的数值。
- 典型场景:当前活跃连接数、CPU 使用率、队列长度。
- Histogram(直方图)
- 语义:对一组观测值进行采样,并统计落在预定义桶(bucket) 中的数量,同时提供总和及总计数。
- 特点:客户端只需记录每个观测值落在哪个桶,服务端可根据桶计算出分位数(近似)。桶的边界是预先定义的,粒度固定。
- 方法:
Observe(float64):记录一个观测值。
- 自定义桶:通过
Buckets参数指定分桶边界(浮点数切片)。如果未指定,使用默认桶DefBuckets。 - 标签注意:通常用
endpoint、method等作为标签,但要注意组合爆炸。 - 典型场景:请求耗时、响应大小(用于计算 P50/P90/P99 延迟)。
- Summary(摘要)
- 语义:和 Histogram 类似,也是记录观测值分布,但它直接在客户端计算滑动时间窗口内的分位数(通过流式算法)。
- 特点:客户端开销较大(需要维护排序结构),但服务端查询时直接获取预计算的分位数,无需再计算。分位数目标(
Objectives)是可配置的,且可以指定误差容忍度。 - 方法:
Observe(float64):记录一个观测值。
- 配置:
Objectives是一个 map,key 为目标分位数(0~1),value 为允许的误差(如 0.01 表示误差 ±1%)。如果不需要分位数,可以传nil,则只记录总和与计数。 - 注意:Summary 的分位数是在客户端计算的,因此长期存储时会保留分位数值,而 Histogram 只存储桶计数,需要服务端用
histogram_quantile()实时计算。 - 典型场景:需要精确分位数且客户端的计算开销可接受时(例如监控本地进程的延迟)。
- Counter(计数器)
- Counter类型示例
package main
import ( "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 定义 Counter 指标 requestsTotal := prometheus.NewCounter( prometheus.CounterOpts{ Name: "myapp_requests_total", Help: "Total number of requests processed.", }, ) prometheus.MustRegister(requestsTotal)
// 模拟每 2 秒增加一次计数 go func() { for { requestsTotal.Inc() // 每次 +1 time.Sleep(2 * time.Second) } }()
// 暴露 /metrics http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}- Gauge类型示例
package main
import ( "math/rand" "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 定义 Gauge 指标 temperature := prometheus.NewGauge( prometheus.GaugeOpts{ Name: "temperature_celsius", Help: "Current temperature in Celsius.", }, ) prometheus.MustRegister(temperature)
// 模拟每 3 秒随机变化 go func() { for { temp := 20 + rand.Float64()*10 // 20~30 度 temperature.Set(temp) time.Sleep(3 * time.Second) } }()
http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}- Histogram类型示例
package main
import ( "math/rand" "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 定义 Histogram(使用默认桶) requestDuration := prometheus.NewHistogram( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Histogram of HTTP request durations.", Buckets: prometheus.DefBuckets, // 默认桶: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10] }, ) prometheus.MustRegister(requestDuration)
// 模拟每 1 秒记录一个随机耗时(0~5 秒) go func() { for { duration := rand.Float64() * 5 requestDuration.Observe(duration) time.Sleep(1 * time.Second) } }()
http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}- Summary类型示例
package main
import ( "math/rand" "net/http" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 定义 Summary(指定目标分位数) responseSize := prometheus.NewSummary( prometheus.SummaryOpts{ Name: "http_response_size_bytes", Help: "Summary of HTTP response sizes.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, ) prometheus.MustRegister(responseSize)
// 模拟每 2 秒记录一个随机响应大小(100~1000 字节) go func() { for { size := 100 + rand.Float64()*900 responseSize.Observe(size) time.Sleep(2 * time.Second) } }()
http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}5. 结尾
没有了喵,谢谢阅读

文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Prometheus+Grafana Exporter的使用
https://blog.tuf3i.cc/posts/grafana-prometheus-explorer/ 相关文章 智能推荐
1
Docker安装Prometheus+Grafana
运维::可观测性 Prometheus和Grafana在Docker上的安装
2
随笔 2026.8.19
生活::随笔 记录一下8月19日发生的事
3
[Auto CQUPT Plan] CAS 统一认证登录逆向(补档)
虫邮::ACP CQUPT-CAS 统一认证登录的完整 HTTP 调用链解析:从获取会话 Cookie 到拿到 ticket 的每一步
4
[Auto CQUPT Plan] 校园网相关接口(补档)
虫邮::ACP 重庆邮电大学校园网API接口总结
5
[Auto CQUPT Plan] HIT SEE 做题自动化(补档)
虫邮::ACP 重庆邮电大学C语言OJ破解
随机文章 随机推荐