首页
/ Prometheus 3.x API 稳定性保证:稳定与不稳定边界及升级实践

Prometheus 3.x API 稳定性保证:稳定与不稳定边界及升级实践

2026-09-06 13:13:41作者:鲍丁臣Ursa

本文基于 Prometheus 仓库中的 API 稳定性文档展开,说明 3.x 版本线中哪些能力受稳定性承诺保护、哪些明确不受保护,并结合仓库源码定位每一项承诺的实际实现位置。读完本文,你可以准确判断自己的查询、配置、告警和集成方式是否处于"升级安全区",并在跨小版本升级前依据 [CHANGE] 标记评估风险。

稳定性承诺的总体原则

Prometheus 的核心承诺只有一句话:在同一个主版本(major version)内保证 API 稳定,并对关键特性尽力避免破坏性变更。原文明确指出,一些"纯外观性的、仍在开发中的、或依赖第三方服务的"特性不在保护范围内。

当前仓库的版本号为 3.14.0(见 VERSION),因此本文讨论的"3.x 稳定性"即为当前代码库所处的版本线。文档末尾给出的实践结论是:

只要你不使用任何被标记为 experimental/unstable 的特性,主版本内的升级通常无需任何运维调整即可进行,出问题的风险极低。所有破坏性变更都会在发布说明(release notes)中以 CHANGE 标记注明。

稳定(Stable)能力清单

文档列出的 3.x 稳定项共 10 条,以下逐项给出说明及仓库内的实现位置佐证。

稳定项 说明 仓库内实现位置
查询语言与数据模型(PromQL) 语言语义、表达式结果模型 promql/parser/promql/engine.go
告警规则与记录规则 规则文件格式与执行语义 rules/,规则校验见 model/rulefmt/
采集暴露格式(exposition format) 文本/Protobuf 解析 model/textparse/
v1 HTTP API 仪表盘和 UI 使用的 /api/v1/* 端点,除显式标记为 experimental 的端点外 web/api/v1/api.go,端点行为见 docs/querying/api.md
配置文件格式 prometheus.yml 各区块(不含服务发现与 remote read/write 部分,见下文不稳定清单) config/config.go
规则/告警文件格式 规则文件的 YAML 语法 model/rulefmt/
Console 模板语法与语义 控制台模板 template/template.go
Remote write 的发送与接收 遵循 1.0 规范 协议定义 prompb/remote.proto,接收端点注册见 web/api/v1/api.go
Agent 模式 --enable-feature=agent 的专用写入模式 cmd/prometheus/main.go 中的 agent 模式逻辑,存储实现 tsdb/agent/
OTLP 接收端点 --web.enable-otlp-receiver 开启的 OTLP 写入入口 cmd/prometheus/main.go 中的 web.enable-otlp-receiver flag

几个值得展开的点:

v1 HTTP API 的"稳定但有例外"。 API 文档中对多个端点(如 status 类、metadata 类端点)明确写着 "This endpoint is experimental and might change in the future",这些端点被排除在稳定性承诺之外。以 docs/querying/api.md 为准,凡是带 experimental 标注的端点都不应作为第三方系统的依赖基础。

Remote write 的双向稳定。 发送侧对应 scrape 后写入远端的队列实现(storage/remote/),接收侧则需要 --web.enable-remote-write-receiver 显式开启;从 web/api/v1/api.goremoteWrite 处理函数的报错信息可以看到,未开启该 flag 时端点直接返回 404。

Agent 模式是 3.x 才纳入稳定承诺的。 从源码结构看,agent 模式有独立 flag 校验(cmd/prometheus/main.go 中的 agentOnlyFlags)与独立存储路径 tsdb/agent/,其配置区块(如 agent_mode.good.yml 示例,见 config/testdata/agent_mode.good.yml)属于配置文件格式中"稳定"的部分。

不稳定(Unstable)能力清单

文档同时列出了 8 类不受稳定性承诺保护的内容,这是升级决策中更重要的一半信息。

1. 所有标记为 experimental 或"可能被修改"的特性

包括:

  • double_exponential_smoothing PromQL 函数:该函数确实存在于函数注册表中(promql/functions.go 第 2696 行附近的函数表),但文档明确将其列为不稳定项,名称、语法、语义都可能变化甚至被整体移除。
  • Remote read 及其端点:服务端入口是 POST /api/v1/read,实现位于 web/api/v1/api.go 第 2165 行起的 remoteRead 处理函数。该端点主要服务于 Thanos 等外部系统读取本地 TSDB,文档将其整体列为不稳定,意味着端点行为与返回格式在 3.x 内都可能变化。

除上述两者外,docs/feature_flags.md 中通过 --enable-feature 开启的所有特性(如 st-storagepromql-extended-range-selectorsotlp-native-delta-ingestionopenmetrics2 等)都默认禁用,文档明确说"其行为可能在未来版本变化",因此同样不在稳定边界内。

2. 服务端 HTTPS 与 Basic 认证

对应配置为 web 配置区块(tls_config 等),入口是 --web.config.file flag(cmd/prometheus/main.go 中的 web.config.file 定义)。从源码结构看,这部分依赖第三方 TLS 库且历史上行为变化较多,故被单列为不稳定项——生产环境建议用反向代理(如 Nginx)承担 TLS 终止。

3. 服务发现集成(例外:static、file、http)

文档给出的例外是 static_configsfile_sd_configshttp_sd_config 三者。源码与之一致:

  • static_configs 是唯一在默认注册表中内置的 Config 类型,discovery/registry.go 第 58 行的注释即声明 "static_configs is the only Config type implemented by default";
  • file SD 与 http SD 分别实现于 discovery/file/file.godiscovery/http/http.go
  • 其余发现器(AWS、Azure、Kubernetes、Consul、Eureka、DNS 等 20 余种)均为插件式注册,源码位于 discovery/ 各子目录,注册插件入口见 plugins/ 目录。这些集成依赖第三方 API/SDK,元标签(__meta_*)与行为可能随版本变化——例如 CHANGELOG 中就有 [CHANGE] Discovery/Hetzner: Drop the __meta_hetzner_datacenter label 这类条目。

4. 服务器内 Go 包的外部 API

即"把 Prometheus 当库引入 Go 项目"不被支持:任何 import "github.com/prometheus/prometheus/..." 中非独立模块(如 prometheus/commonprometheus/client_golang)的包,其导出符号都可能变化。

5. Web UI 生成的 HTML

3.0 起 UI 是一次完整重写(web/ui/ 目录包含全新前端工程),生成的 DOM/HTML 结构不属于任何 API 契约,自动化测试不应断言 UI 的 HTML。仓库甚至保留了 old-ui feature flag 让用户回退到 2.x 旧界面(见 docs/feature_flags.md 的 "Serve old Prometheus UI" 一节)。

6. Prometheus 自身 /metrics 端点的指标

prometheus_* 自监控指标的命名、标签维度可以变化,不应作为对外契约。CHANGELOG 中有真实案例:[CHANGE] Alerting: Add alertmanager dimension to following metrics: prometheus_notifications_dropped_total, ...

7. 精确的磁盘存储格式

TSDB 的 block/WAL 落盘细节不保证兼容,但文档给出了一条重要兜底:未来的变更将保持向前兼容(forward compatible),并由 Prometheus 透明处理。从源码结构看,这对应 TSDB 的块写入与修复机制(tsdb/block.gotsdb/repair.go)以及 WAL(tsdb/wlog/)。换言之,低版本写的数据高版本能读,但不要期望反向兼容。

8. 日志格式

util/logging/ 输出的日志行结构不作为稳定 API,不要把运维脚本建立在"逐字符解析日志行"之上。

主版本内升级:用 [CHANGE] 标记做风险扫描

稳定与不稳定清单之外,仓库提供了可操作的变更审计机制:CHANGELOG.md 中所有破坏性变更统一以 [CHANGE] 前缀标注。当前 CHANGELOG.md 中这类条目大量存在,例如:

- [CHANGE] API: Deprecate the `stats` query parameter of `/api/v1/query`
  and `/api/v1/query_range` for values other than `true` and `all`. ...
- [CHANGE] PromQL: Enable duration expressions by default.
  The `promql-duration-expr` feature flag is now a no-op.
- [CHANGE] Discovery/Hetzner: Drop the `__meta_hetzner_datacenter` label
  for `hcloud` targets, ...

值得注意的是,3.0 主版本本身就集中引入了若干破坏性变更(如移除隐式文本格式回退、le/quantile 标签值归一化、auto-gomaxprocs 等),这些在 CHANGELOG 的 3.0.0 小节中均以 [CHANGE] 逐条列出,并指向迁移指南(docs/migration.md)。

由此可以总结出升级工作流:

  1. 盘点依赖面:确认自己用到的端点是否带 experimental 标注(docs/querying/api.md)、是否依赖 remote read、是否解析 SD 元标签或自监控指标;
  2. 扫描 [CHANGE]:从当前版本到目标版本,逐条阅读 CHANGELOG 中的 [CHANGE] 条目,只关注与自己依赖面相关的部分;
  3. 避免锁定不稳定项:不要把 __meta_* 标签、UI 的 HTML、日志行格式、自监控指标名称写进下游系统的硬依赖;
  4. 实验特性按需启用并预期变动--enable-feature 开启的特性文档承诺"行为可能变化",升级前应复查 docs/feature_flags.md 中对应条目的最新说明(其中部分 flag 已废弃并迁移到配置文件,如 extra-scrape-metrics 迁移为 extra_scrape_metrics 配置项、xor2-encoding 迁移为 chunk_encoding.floats 配置)。

小结

docs/stability.md 的价值在于给出了一个可执行的"依赖白名单":PromQL 与数据模型、规则、采集格式、v1 HTTP API(非实验端点)、配置文件、remote write、Agent 模式与 OTLP 接收端点构成 3.x 的升级安全区;而实验特性、remote read、服务端 TLS/Basic 认证、绝大多数服务发现集成、Go 内部包、UI HTML、自监控指标、磁盘细节格式与日志格式则处于承诺边界之外。只要把下游系统约束在白名单内,并升级前按 [CHANGE] 标记做一次变更扫描,主版本内的滚动升级就能做到接近零运维成本。

登录后查看全文
热门项目推荐
相关项目推荐