Prometheus 抓取结果主题封面,展示观察、判断与行动三个步骤。

Prometheus 主动抓取指标,并记录抓取结果

Prometheus 会主动请求每个已配置目标的 HTTP 指标端点。目标负责暴露观测值,采集器决定抓取时刻、解析响应并保存样本。这种安排让采集故障能够从采集器一侧被看见,但不能保证端点一定可达、所有预期目标都被发现,也不能保证用户的登录或下单流程正常。理解这些边界,才能把采集结果转换成准确的告警和排查动作。 一个任务包含多个独立抓取的实例 任务通常把用途相同的目标组织在一起,例如一组接口服务副本。每个目标仍是独立实例,具有自己的抓取结果。常见的 job 与 instance 标签标识这层上下文,最终标签也可能经过重新标记而改变。服务发现提供候选目标,抓取配置再决定实际访问的端点、协议、周期、超时和认证方式。因此,目标没有被发现与目标已经配置但抓取失败,是两类不同的问题。 采集器必须能够连接目标。虽然导出器不需要主动向采集器上传指标,目标仍然需要允许经过授权的采集器访问其入站端口。网络策略、证书身份、认证凭据与路由不会因为采用拉取模式而消失。拉取只是改变连接由哪一方发起,不能把任意导出器变成可以直接暴露在公网的安全接口。部署时要从采集器所在网络检查这条路径。 准确理解系统生成的指标 对于已配置的实例,Prometheus 会生成 up 指标,抓取成功时为一,失败时为零。它是指标名称,不是所谓的 up 标签。抓取耗时与样本数量则补充了采集质量的证据。导出器可能在后端数据库不可用时仍返回合法响应,也可能漏掉一项重要业务指标,因此即使 up 为一,也不能推导后端依赖和全部业务观测都正常。 这些进一步的问题应由应用结果指标、导出器专门提供的依赖状态,以及实际业务探测回答。反过来,up=0 描述的是采集失败,监控网络故障可能使它变为零,而用户请求仍然成功。告警措辞应写清采集目标与错误证据,避免让响应人员把所有监控链路问题直接当成客户故障。业务影响仍需要另一组证据确认。 坏掉的样子 连接被拒绝、请求超时、证书校验失败或导出格式无效,都可能让抓取失败。先查看目标的最近抓取错误,再决定需要调整什么。延长周期无法修复错误端口;增大超时可能让缓慢的导出器看起来恢复,却不会消除它的执行成本。采集变贵时还应检查输出序列数量和响应大小,确认是否新增了不必要的标签组合或昂贵查询。抓取超时不能超过配置周期,缩短周期前则应评估导出器负载。更快的轮询可能成倍增加导出器对数据库的查询次数,却不会降低每次查询的成本。 从服务发现中移除的目标,与继续存在但返回零的目标不同。前者的对应序列之后可能不再出现在即时查询中,所以把全站 up 求和,并不能证明所有预期实例仍然存在。需要完整性保证时,应把发现结果与实际部署清单对照。单独请求一次 /metrics 成功,同样不能代替登录、支付或订单提交的功能验证。 快速验证 把下面程序保存为 pull.py,在 Docker 可用的环境执行 python3 pull.py。程序使用 prom/prometheus:v3.5.1,如果本机尚未缓存镜像,首次运行需要从镜像仓库下载。实验只创建一个一次性容器,让其中的 Prometheus 抓取自己的回环端点,以及回环地址上没有服务监听的端口。它不发布宿主机端口,容器也无法访问外部网络。 import json import subprocess import uuid # Requires Docker and the public Prometheus 3.5.1 image. # All HTTP traffic stays on loopback inside one disposable container. script = r"""set -eu cat > /tmp/prom.yml <<'CONFIG' global: scrape_interval: 1s scrape_timeout: 500ms scrape_configs: - job_name: self static_configs: - targets: ['127.0.0.1:9090'] - job_name: refused static_configs: - targets: ['127.0.0.1:1'] CONFIG /bin/prometheus --config.file=/tmp/prom.yml --storage.tsdb.path=/tmp/data \ --web.listen-address=127.0.0.1:9090 > /tmp/prom.log 2>&1 & for attempt in $(seq 1 30); do if wget -qO /tmp/ready.json 'http://127.0.0.1:9090/api/v1/query?query=count%28up%29%20%3D%3D%202%20and%20sum%28up%29%20%3D%3D%201'; then if grep -q '"status":"success"' /tmp/ready.json && ! grep -q '"result":\[\]' /tmp/ready.json; then wget -qO- 'http://127.0.0.1:9090/api/v1/query?query=up' exit 0 fi fi sleep 1 done cat /tmp/prom.log >&2 exit 1 """ name = "xbcatm-prom-live-" + uuid.uuid4().hex[:12] try: result = subprocess.run( ["docker", "run", "--rm", "--name", name, "--network", "none", "-i", "--entrypoint", "/bin/sh", "prom/prometheus:v3.5.1", "-s"], input=script, text=True, capture_output=True, timeout=45, ) finally: subprocess.run(["docker", "rm", "-f", name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if result.returncode: raise RuntimeError(result.stderr or result.stdout) payload = json.loads(result.stdout) assert payload["status"] == "success" values = {item["metric"]["job"]: float(item["value"][1]) for item in payload["data"]["result"]} assert values == {"self": 1.0, "refused": 0.0}, values print(json.dumps({"up_by_job": values, "scrape_reachability_only": True}, indent=2)) 结果应当包含 self: 1.0 和 refused: 0.0。程序等待两个目标都有抓取结果,再通过查询接口进行断言,因此不会把启动期间数据库暂时为空误判成配置失败。退出清理仅针对本次随机命名的容器,不涉及其他容器。这个结果证明真实采集器可以区分成功抓取与连接拒绝;它没有测试业务功能,也没有证明服务发现清单完整。 ...

八月 30, 2027 · 2 分钟 · XB Field Notes