Prometheus 核心配置详解与常用监控场景落地
一、开篇:从「能跑」到「能用」,配置是监控的核心
1.1 承接上篇:单机部署完成后,我们还差什么
在上一篇文章中,我们成功完成了 Prometheus 的基础安装,并且看到了自带的 Web UI 界面。但这仅仅是“能跑”的状态。一个监控系统如果只能监控自己,显然毫无意义。在实际生产环境中,我们需要将服务器、数据库、中间件、业务应用等统统纳入监控版图,而这一切的指挥中枢,就是 Prometheus 的核心配置文件——prometheus.yml。
不仅如此,随着监控规模的扩大,如何高效地管理这些目标、如何对海量指标进行分类和过滤、如何在动态的云原生环境中实现自动发现,这些都是摆在每个运维和开发人员面前的现实挑战。
1.2 本篇学习目标
通过本篇内容的深度学习,你将达成以下进阶目标:
- 吃透配置文件:彻底搞懂
prometheus.yml的骨架与核心参数,掌握超时、抓取频率与资源消耗的平衡艺术。 - 解析核心指标类型:在接入监控之前,弄懂 Counter、Gauge、Histogram、Summary 四大数据模型,为后续写 PromQL 扫清障碍。
- 熟练接入监控对象:掌握实操,亲手接入至少 3 类常用的监控目标(Linux主机、MySQL、Nginx、Docker),并理解其背后的原理。
- 玩转高级标签管理:深入理解 Relabel 的机制,掌握如何通过配置在抓取前后对数据进行清洗和重塑。
- 掌握通用排错思路:在遇到 Target 处于
Down状态时,能快速定位网络、认证、配置等维度的问题并解决。
1.3 学习前置说明
为了兼顾不同背景的读者,本文的实操部分全程沿用「二进制 + Docker」双部署方案。你可以根据自己公司的实际技术栈,按需选择对应的方法。无论是哪种方式,其核心的监控原理是完全一致的。
二、吃透 prometheus.yml:核心配置结构全拆解
打开 Prometheus 的配置文件 prometheus.yml,很多新手会被密密麻麻的参数吓退。其实,它的结构非常清晰,完全是模块化的设计。
2.1 配置文件整体骨架:三大核心配置段一览
整个配置文件主要由三大核心配置块(Block)组成,就像人的头部、躯干和四肢,各司其职:
# 1. 全局配置段:定义 Prometheus 的默认抓取与评估规则global: # ...
# 2. 规则文件段:定义告警规则和记录规则的路径,是实现主动告警的基础rule_files: # ...
# 3. 抓取配置段:定义要监控的具体目标和抓取任务(重中之重)scrape_configs: # ...2.2 global 全局配置段:小白必懂参数
global 段定义了全局的默认参数,其他未单独配置的任务都会继承这些设置。这部分虽然代码不多,但直接影响着整个监控系统的性能和实时性。
global: # 全局抓取间隔,多久去目标那里拉取一次数据,默认 15s scrape_interval: 15s
# 抓取超时时间,必须严格小于等于 scrape_interval,默认 10s scrape_timeout: 10s
# 规则评估周期,多长时间计算一次告警规则或记录规则,默认 15s evaluation_interval: 15s
# 外部标签:当数据发送给外部系统(如 Thanos 联邦集群、Alertmanager 告警中心)时,附加的全局标识标签 external_labels: cluster: 'prod-beijing' monitor: 'prometheus-main' datacenter: 'aliyun-bj'参数调优与资源权衡
scrape_interval决定了监控数据的细腻程度。
- 间隔越短:数据越精准,能捕捉到瞬间的毛刺(如 CPU 突增),但 TSDB 存储和网络开销也越大。
- 间隔越长:节省资源,但可能漏掉短暂的异常波动。 一般生产环境推荐设置为
15s到30s之间。对于极度核心的业务接口,可以在具体的scrape_configs中将其覆盖为5s。
2.3 rule_files 规则文件段
这个配置块用于告诉 Prometheus 去哪里加载规则文件。规则主要分为两类:
- 告警规则(Alerting Rules):当指标满足特定条件(如 CPU 超过 80% 持续 5 分钟)时触发告警事件,并推送给 Alertmanager。
- 记录规则(Recording Rules):对于那些高频查询且计算复杂的 PromQL(比如求整个集群的总 QPS),可以通过记录规则让 Prometheus 在后台定期算好,并保存为一个新的普通指标。这样在 Grafana 看板查询时,速度会得到质的飞跃。
rule_files: # 支持绝对路径或相对路径(相对于 prometheus.yml 所在目录) # 强烈建议按业务或组件模块化拆分规则文件 - "rules/record/node_rules.yml" - "rules/record/mysql_rules.yml" - "rules/alert/system_alerts.yml" - "rules/alert/middleware_alerts.yml"2.4 scrape_configs 抓取配置段:重中之重
这是我们平时改动最频繁的地方,用于定义具体去哪里拉取监控数据。每一个任务(Job)都可以在这里拥有定制化的抓取策略。
scrape_configs: # job_name 必须在当前配置中唯一,抓取回来的数据会自动打上 job="prometheus" 的标签 - job_name: 'prometheus'
# 覆盖 global 的全局抓取间隔,针对这个 job 单独生效 scrape_interval: 5s
# 自定义指标接口路径,默认是 '/metrics'。有些 Java 应用可能是 '/actuator/prometheus' metrics_path: '/metrics'
# 协议配置,默认 'http'。如果目标开启了 TLS,需改为 'https' scheme: 'http'
# HTTP 基本认证(如果目标指标接口有密码保护) basic_auth: username: 'admin' password: 'strong_password'
# 静态配置目标 static_configs: - targets: ['localhost:9090'] # 为这组 target 追加自定义标签,方便后续按环境过滤 labels: env: 'dev' tier: 'infra'Job 与 Target 的核心概念
- Target(目标):一个暴露了
/metrics接口的具体实例进程,比如192.168.1.10:9100,它对应一台物理机的 Node Exporter。- Job(任务):一组相同目标的逻辑集合。比如 10 台 Web 服务器的 Node Exporter 监控目标,可以组合成一个名为
web-nodes的 Job。通过 Job,我们可以对这一批同构的节点实施统一的抓取策略。
三、四大核心指标类型(Metrics Types)前瞻
在动手接入 Exporter 之前,我们有必要先认识一下 Prometheus 数据模型中的四大基本指标类型。这就像是学编程必须先懂数据类型一样,直接决定了你以后会不会写 PromQL。
3.1 Counter(计数器)
特点:只增不减(除非系统重启导致清零)。
适用场景:记录事件发生的总次数,比如:HTTP 请求总数、出现错误的次数、已处理的订单总数。
常用函数:rate()。我们通常不关心 Counter 的绝对值,而是关心它的增长速率(如 QPS)。例如 rate(http_requests_total[5m]) 计算过去 5 分钟的平均每秒请求数。
3.2 Gauge(仪表盘)
特点:可增可减,反映当前状态的瞬时值。
适用场景:记录当前的状态,比如:当前 CPU 使用率、当前内存剩余量、当前并发连接数、当前队列堆积长度。
常用用法:直接使用,或者用作简单的数学运算。比如 node_memory_MemFree_bytes / 1024 / 1024 查看当前剩余多少 MB 内存。
3.3 Histogram(直方图)
特点:将数据放入预先定义好的“桶(Bucket)”中,用于统计数据分布。
适用场景:记录请求的响应时间大小分布、文件上传的体积大小分布。
常用函数:histogram_quantile()。用于计算分位数,比如经典的 P99 延迟:histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))。
3.4 Summary(摘要)
特点:类似于 Histogram,也是用于计算分位数。但它的分位数是在客户端(应用内部)直接算好的,服务器端拿到的直接就是分位数结果。 适用场景:与 Histogram 类似,但由于客户端直接计算,服务器端压力小,缺点是不能将多个实例的 Summary 数据进行聚合。
了解了这四种类型,当你访问 Exporter 的 /metrics 接口时,看到类似 # TYPE node_cpu_seconds_total counter 的注释,就能立刻明白该如何使用这个指标了。
四、通用技能:如何接入一个新的监控目标
理解了配置和指标类型,我们开始动手接入监控对象。
4.1 Exporter 工作原理再梳理
在 Prometheus 的生态中,Exporter 是监控目标与 Prometheus 服务器之间的核心桥梁。
- 绝大多数软件(如 Nginx、MySQL、Redis)原生并不提供符合 Prometheus 规范的监控数据。
- Exporter 的作用就像一个“翻译官”,它通过调用被监控软件自身的 API(如 Nginx 的 stub_status,MySQL 的 show status 命令),获取运行状态,然后将其格式化为 Prometheus 认识的带标签的纯文本
/metrics格式。
接入四步法:
- 选 Exporter:在社区寻找官方(如官方维护的 node_exporter)或主流的第三方 Exporter。
- 部署启动:以二进制或 Docker 方式运行 Exporter,确保其能正常访问被监控服务。
- 加抓取配置:在
prometheus.yml的scrape_configs中新增 Job。 - 验证状态:在 Prometheus UI 中确认 Target 状态为
Up。
4.2 实操:部署 Node Exporter 监控 Linux 主机
Node Exporter 用于采集类 UNIX 系统的硬件和操作系统级指标(CPU、内存、磁盘 IO、网络吞吐等)。
方式一:二进制包部署(适合传统裸机架构)
# 1. 下载并解压wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gztar -xvf node_exporter-1.7.0.linux-amd64.tar.gzsudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/
# 2. 配置 Systemd 托管(确保开机自启和异常重启)sudo tee /etc/systemd/system/node_exporter.service <<EOF[Unit]Description=Node ExporterAfter=network.target
[Service]User=root# 可以通过附加参数关闭不需要的收集器以节省资源,如 --no-collector.zfsExecStart=/usr/local/bin/node_exporterRestart=on-failure
[Install]WantedBy=multi-user.targetEOF
# 3. 启动服务并放行 9100 端口sudo systemctl daemon-reloadsudo systemctl enable --now node_exportersudo ufw allow 9100/tcp # 如果开启了 UFW 防火墙方式二:Docker 一键部署(适合容器化环境)
由于 Node Exporter 需要采集宿主机的硬件信息,必须挂载宿主机的根目录和相关系统伪文件系统(如 /proc 和 /sys):
docker run -d \ --name=node-exporter \ --net=host \ --pid=host \ -v "/:/host:ro,rslave" \ quay.io/prometheus/node-exporter:latest \ --path.rootfs=/hostDocker 部署注意事项注意
--net=host和--pid=host参数,它们让容器直接共享宿主机的网络命名空间和进程命名空间,这样 Node Exporter 才能准确采集到宿主机的网络指标和进程信息,同时也会直接在宿主机上监听默认的9100端口。
验证 Exporter 接口:
打开浏览器访问 http://<服务器IP>:9100/metrics,如果看到密密麻麻的、以 # HELP 和 # TYPE 开头的纯文本数据,说明 Exporter 部署成功!
4.3 在 Prometheus 中新增主机监控任务
回到 Prometheus 所在机器,编辑 prometheus.yml:
scrape_configs: # 之前的配置...
- job_name: 'linux-nodes' static_configs: - targets: ['192.168.1.10:9100', '192.168.1.11:9100'] labels: os: 'ubuntu' datacenter: 'zone-a'配置热重载:不重启服务生效新配置
改完配置文件后,千万不要直接重启 Prometheus 进程!重启不仅会导致监控服务短暂中断,对于海量指标的系统,重新加载内存数据需要耗费大量时间和 CPU。我们应使用热重载机制:
# 方法一:发送 SIGHUP 信号(适用于二进制部署的进程)kill -HUP $(pidof prometheus)
# 方法二:调用 Lifecycle HTTP API(适用于 Docker 或二进制)# 注意:前提是 Prometheus 启动时带上了 --web.enable-lifecycle 参数curl -X POST http://localhost:9090/-/reload4.4 目标状态验证与深度排错指南
打开 Prometheus 的 Web UI,点击顶部菜单栏 Status -> Targets。
- 如果显示绿色的 UP,恭喜你,接入成功!
- 如果显示红色的 DOWN,也不用慌,重点看右侧的
Error信息列。
Down 状态高频排查思路大全
- Get “http://x.x.x.x:9100/metrics”: dial tcp… connect: connection refused
- 含义:Prometheus 服务器发出的 TCP 连接被目标机器拒绝。
- 排查:检查目标机器的 Exporter 进程是否 Crash;检查目标机的 iptables/firewalld 防火墙是否放行了对应端口;如果是云服务器,必须检查云控制台的安全组入方向规则是否放行。
- HTTP status 404 Not Found
- 含义:TCP 连通了,但请求的路径不存在。
- 排查:可能是
metrics_path配置错了(比如某些 Java 应用是/actuator/prometheus);或者目标服务本身暴露的端口不对,你连到了别的 Web 服务上。- HTTP status 401 Unauthorized / 403 Forbidden
- 含义:目标接口需要认证。
- 排查:在
prometheus.yml的对应 Job 中补充basic_auth或bearer_token配置。- context deadline exceeded
- 含义:连接或读取数据超时。
- 排查:目标处理
/metrics请求过慢(可能是指标数量极其庞大),或者网络延迟过高。可尝试在 Job 级别调大scrape_timeout(注意不能超过scrape_interval)。
五、高频场景落地:3 类常用服务监控一键接入
掌握了基础,我们来看看实际业务中最常用的中间件是如何接入监控的。
5.1 MySQL 数据库监控:mysqld_exporter
MySQL 的监控通过官方维护的 mysqld_exporter 实现。它可以深入挖掘 MySQL 的性能瓶颈。
前置准备:创建监控专用只读用户
为了安全起见,绝对不要使用 root 账号让 Exporter 连接数据库,我们需要建立一个权限最小化的监控账号:
CREATE USER 'exporter'@'%' IDENTIFIED BY 'complex_password';-- 赋予查看进程、主从状态和全局状态的权限GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';FLUSH PRIVILEGES;部署 mysqld_exporter(以 Docker 为例)
docker run -d \ --name mysqld-exporter \ -p 9104:9104 \ -e DATA_SOURCE_NAME="exporter:complex_password@(192.168.1.50:3306)/" \ prom/mysqld-exporterPrometheus 配置接入
- job_name: 'mysql-cluster' static_configs: - targets: ['192.168.1.10:9104'] labels: role: 'master'核心指标预览:
接入后,你可以关注 mysql_global_status_threads_connected(当前连接数)、mysql_global_status_queries(总查询数,可用 rate 算 QPS)、mysql_global_status_slow_queries(慢查询累计数)。
5.2 Nginx 服务监控:nginx-prometheus-exporter
Nginx 自身提供了一个基础的状态页面,Exporter 就是通过读取这个页面来生成指标的。
前置条件:Nginx 开启 stub_status
编辑 Nginx 配置文件(通常在 /etc/nginx/conf.d/default.conf),添加一个隐藏的 location 暴露状态接口:
server { listen 8080; location /stub_status { stub_status on; access_log off; # 监控请求频繁,关闭日志避免磁盘写满 # 安全建议:只允许内网或监控服务器 IP 访问 allow 127.0.0.1; allow 192.168.1.0/24; deny all; }}重载 Nginx 配置:nginx -s reload。
部署 nginx-prometheus-exporter(以 Docker 为例)
docker run -d \ --name nginx-exporter \ -p 9113:9113 \ nginx/nginx-prometheus-exporter:latest \ -nginx.scrape-uri http://192.168.1.10:8080/stub_statusPrometheus 配置接入
- job_name: 'nginx-proxy' static_configs: - targets: ['192.168.1.10:9113']5.3 Docker 容器监控:cAdvisor
虽然 Node Exporter 能监控宿主机整体,但看不了具体每个容器占用的资源(比如哪个容器 CPU 飙升了)。此时我们需要用到 Google 开源的神器 cAdvisor。
Docker 方式快速部署 cAdvisor
cAdvisor 需要挂载大量的底层系统文件,才能解析出 Docker Daemon 和 cgroup 的资源限制信息:
docker run -d \ --name=cadvisor \ -p 8080:8080 \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:ro \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --volume=/dev/disk/:/dev/disk:ro \ --privileged \ --device=/dev/kmsg \ gcr.io/cadvisor/cadvisor:latestPrometheus 配置接入
- job_name: 'docker-containers' static_configs: - targets: ['192.168.1.10:8080']热重载后,在 Prometheus 页面查询 container_memory_usage_bytes 就能看到细粒度到容器名称(name="xxx" 标签)的内存指标了。
六、标签与重打标签(Relabel)进阶实战
6.1 标签的核心价值:为什么 Prometheus 如此看重标签
在传统的监控系统中,指标通常是树形结构的(如 server.app1.cpu.usage)。而在 Prometheus 中,指标是多维度的,依靠**标签(Labels)**的组合来区分不同的时间序列。标签是数据筛选、分组聚合、多维度统计的灵魂。
比如:http_requests_total{method="GET", status="200", env="prod"}。通过修改查询条件,我们可以轻松聚合出整个 prod 环境的 QPS,或者细化到某个具体接口的 500 错误率。
Prometheus 会在抓取前生成一些极其重要的内置标签(Meta Labels,以 __ 开头):
__address__:目标的地址<host>:<port>__metrics_path__:指标路径,默认/metrics__scheme__:协议,http或https
6.2 最常用的 3 种 relabel 场景深度解析
**Relabel(重打标签)**允许你在抓取数据前,动态地修改、删除、增加标签,甚至是过滤监控目标。这是高级 Prometheus 玩家必须掌握的杀手锏。
场景一:replace - 给所有目标统一添加或提取自定义标签
- job_name: 'api-servers' static_configs: - targets: ['10.0.0.1:80', '10.0.0.2:80'] relabel_configs: # 示例:强制将所有数据打上 project=myapp 的标签 - source_labels: [__address__] target_label: project replacement: 'myapp' action: replace场景二:keep / drop - 目标级过滤,只保留需要的节点
在结合动态服务发现(如 Kubernetes)时,我们可能会发现一大批节点,但只想监控特定的几个。
- job_name: 'nodes' static_configs: - targets: ['10.0.0.1:9100', '10.0.0.2:9100'] labels: env: 'test' relabel_configs: # 动作:只有当目标自带的 env 标签值为 prod 时,目标才会被加入抓取队列,其他的直接丢弃 - source_labels: [env] regex: 'prod' action: keep场景三:labelmap - 批量映射标签名
在云原生环境中,服务发现通常会返回一堆带有前缀的元数据标签,我们可以用 labelmap 批量清洗它们。
- job_name: 'k8s-pods' # 假设服务发现返回了形如 __meta_kubernetes_pod_label_app="nginx" 的元标签 relabel_configs: # 动作:将所有匹配正则的标签名,提取第一个捕获组,重命名为新标签 # 结果:生成普通标签 app="nginx" - action: labelmap regex: __meta_kubernetes_pod_label_(.+)6.3 避坑提醒:relabel 生效时机与配置顺序
Relabel 高级避坑指南
- 生效阶段差异:
relabel_configs发生在抓取数据之前,主要用于对 Target 的连接属性(如改端口、改路径)进行调整,或者过滤 Target 本身。metric_relabel_configs发生在抓取数据之后,存入 TSDB 之前。如果是想修改或丢弃已经被 Exporter 吐出来的指标内部的标签,必须使用这个配置。- 执行顺序:Relabel 配置是按 YAML 列表顺序自上而下逐条执行的,上一步修改的结果会作为下一步的输入。如果逻辑顺序配反,可能导致匹配不到预期的结果。
七、服务发现基础:告别手动逐个加目标
7.1 静态配置的痛点
目前为止,我们用的都是 static_configs。当机器只有几台时,手写 IP 没问题。但在云原生和弹性伸缩的时代,如果公司有 500 台机器,每天都在根据流量扩缩容,手动修改 prometheus.yml 并且每次都 Reload 显然是灾难,极易引发遗漏或监控报错。
7.2 入门首选:基于文件的服务发现(File SD)
Prometheus 提供了极简且强大的 file_sd_configs 机制:让 Prometheus 定时去读取指定的 JSON 或 YAML 文件,只要文件内容发生变化,内存中的监控目标队列就会自动热更新。
实操演示:
- 在 Prometheus 配置目录下创建
targets/文件夹,新建一个nodes.json文件:
[ { "targets": ["192.168.1.10:9100"], "labels": { "env": "prod", "region": "beijing", "team": "core-backend" } }, { "targets": ["192.168.1.11:9100"], "labels": { "env": "test", "region": "shanghai", "team": "qa" } }]- 修改
prometheus.yml,接入文件发现:
- job_name: 'dynamic-nodes' # 彻底移除 static_configs,替换为 file_sd_configs file_sd_configs: - files: - 'targets/nodes.json' # 探测文件的刷新频率,默认 5m。文件有变动时 Prometheus 会自动加载新目标 refresh_interval: 1m配置完成后,使用 API Reload 一次 Prometheus。以后再新增机器,只需要用 Shell 脚本、Ansible 或者公司的 CMDB 系统去自动修改 nodes.json 即可,Prometheus 服务本身完全无需重启或 Reload。这极大地解耦了监控系统与资产管理系统。
7.3 常见服务发现方式简介:为进阶铺垫
除了文件发现,Prometheus 社区内置了数十种原生的服务发现(Service Discovery)机制,适配各大云厂商和注册中心:
- Consul SD (
consul_sd_configs):连接 Consul 注册中心,适用于微服务架构。微服务启动时向 Consul 注册,Prometheus 通过长轮询自动发现并抓取,实现真正的无缝监控。 - Kubernetes SD (
kubernetes_sd_configs):云原生环境的标配。通过调用 K8s APIServer,自动发现集群内的 Node、Pod、Endpoint、Service 等所有资源,配合 Relabel 规则,这是 Prometheus Operator 能够自动监控整个 K8s 集群的底层魔法。 - 云厂商 SD(如
ec2_sd_configs,aliyun_sd_configs):直接调用 AWS 或阿里云的 API,自动将云账号下的 ECS 实例全部纳管。
八、本篇小结
8.1 核心知识点复盘清单
- 掌握
prometheus.yml三大段:全局 (global) 影响性能与频率、规则 (rule_files) 奠定告警基础、抓取 (scrape_configs) 定义目标策略。 - 深刻理解了 Counter、Gauge 等四大指标类型,为编写 PromQL 奠定理论基础。
- 熟悉 Exporter 工作流,成功部署 Node、MySQL、Nginx、cAdvisor 等主流监控组件。
- 掌握配置热重载技巧 (
kill -HUP或/-/reload),保证监控系统的高可用。 - 理解 Relabel 的强大之处,区分了抓取前与抓取后的处理时机,掌握
replace、keep、labelmap的应用场景。 - 掌握基于文件(
file_sd_configs)的动态服务发现机制,迈出监控自动化的第一步。
8.2 小白高频踩坑汇总与自查表
| 故障现象 | 根本原因分析 | 解决 / 自查方法 |
|---|---|---|
| Targets 页面完全搜不到配置的目标 | YAML 缩进错误或 Job 未被加载 | 执行 ./promtool check config prometheus.yml 严格检查语法 |
Target 状态 DOWN,报错 connection refused | 目标机器拒绝 TCP 连接 | 宿主机执行 curl http://ip:port/metrics,重点排查云安全组和本地防火墙 |
| 无法通过 HTTP API Reload 配置 | 启动时缺少关键授权参数 | 检查启动命令是否明确包含了 --web.enable-lifecycle |
| Exporter 看不到主机数据(Docker部署时) | 容器与宿主机隔离导致 | 检查 --volume=/:/host:ro 挂载路径及 --net=host 是否正确配置 |
| 指标抓取回来了但过滤标签没生效 | relabel 与 metric_relabel 用混了 | 若要修改已拉取指标内部的标签,必须改为 metric_relabel_configs |
下一篇预告: 我们现在已经收集到了海量的监控数据,但 Prometheus 自带的界面过于简陋,难以直观分析。下一篇文章,我们将正式进入数据可视化的世界,手把手教你部署 Grafana,导入酷炫的官方模板,并初步学习 PromQL 语法,打造属于你自己的企业级监控大屏,敬请期待!