想象市第一体检中心的一天:门口导诊台把印着统一格子的体检单发给每一位客人,项目名、数值、参考范围一一对齐;各科室护士用血压计、体温计测量,把结果填进同一张单子;总检医生按固定时间收齐报告,统一解读。没有人问“这单子怎么填”,因为大家遵循同一套填写规范。 监控系统也一样。应用就像体检者,Exporter 就像血压计和体温计,Prometheus 则是定期收单的总检医生。而 OpenMetrics 就是那张全国统一的体检单——它规定了指标“长什么样”(数据模型)、“怎么填”(Exposition 格式),让任何应用产出的指标都能被任何采集系统读懂。本文就带你先看清这张“体检单”,再亲手做一台合格的“体检仪器”,最后让它与总检医生顺畅配合。

岗位关联

掌握 OpenMetrics 与 Exporter 开发,是搭建标准化可观测体系的核心能力,也是 SRE 与可观测性工程师面试必考、日常排障必备的硬技能。

目录
  1. 可视化演示
  2. 三大支柱
  3. 数据模型
  4. 格式规范
  5. Exporter 开发
  6. 集成实践
  7. 性能优化
  8. 测试调试
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

三大支柱

体检中心门口挂着三块牌子:“基础体检”、“问诊记录”、“检查单流转”。基础体检测体温、量血压,输出一个个数值;问诊记录写下病人描述和医生观察,是一段段文字;检查单流转则追踪“这张单子到过哪个科室、下一步该去哪”。三块牌子服务同一个目标:全面了解病人状况。

软件系统的可观测性(Observability)也由三根支柱撑起:Metrics 指标、Logs 日志、Traces 链路追踪。Metrics 是数值型快照,适合聚合与告警;Logs 是离散事件文本,适合排查细节;Traces 是请求跨服务的传播路径,适合定位瓶颈。三者各有所长,互为补充。

本文的主角 OpenMetrics,正是为 Metrics 这根支柱定制的“体检单”标准。它不关心日志怎么写,也不管链路用什么协议,只专注解决一个问题:让任何应用吐出的指标都长成一个样,任何采集系统都能直接读懂。理解这一点,你就知道 OpenMetrics 在可观测性版图里的位置了。

回到体检中心,三块牌子缺一不可;而 OpenMetrics 要做的,就是先把“基础体检”这一块的报告单格式彻底统一。统一之后,下一节我们仔细端详这张体检单上究竟印了哪些格子。

Observability=Metrics∪Logs∪Traces\displaystyle Observability = Metrics \cup Logs \cup Traces
公式说明:可观测性由三类数据共同构成,OpenMetrics 只负责其中 Metrics 部分的标准化。
  1. 可观测性(Observability)系统内在状态可被外部测量的能力,就像体检中心对病人健康状况的全面掌握。
    ObservabilityObservability
  2. 并集(\cup)表示三者之和,缺一不可。没有数值只有日志,无法快速告警;没有日志只有数值,难以定位根因。
    ∪\cup
  3. 三支柱集合$Metrics \cup Logs \cup Traces$ 共同构成完整可观测性,OpenMetrics 站在 Metrics 这一支柱上。
    Metrics∪Logs∪TracesMetrics \cup Logs \cup Traces

数据模型

拿起体检中心的统一体检单,你看到的格子由四部分拼成:项目名称(比如“血压”)、被检人信息(姓名、年龄)、测得数值(120/80)、测量时刻(08:30)。缺了任何一项,总检医生都无法准确解读。OpenMetrics 的数据模型与之惊人相似。

OpenMetrics 把一次“指标测量”称为一个样本(Sample)。样本由四要素构成:指标名(Metric Name)、标签集合(Labels)、值(Value)和时间戳(Timestamp)。指标名告诉你“测的是什么”,标签告诉你“测的是谁”,值和时间戳告诉你“结果如何、何时测得”。

指标名遵循命名规范:通常为 namespace_subsystem_unit_suffix,例如 http_requests_total 由 namespace(http)+ 单位(requests)+ 类型后缀(total)组成。标签是 key-value 对,同样的指标名配上不同标签,就构成不同的时间序列。类型上,Counter 只增不减,Gauge 可增可减,Histogram 记录分布,Summary 在客户端计算分位数,Info 描述静态信息,StateSet 表示状态枚举。

这样一张格子分明的体检单,让总检医生一眼就知道每个数字的含义。但要注意:格子设计得再好,填写规范不统一,各科室还是各写各的——这正是下一节“填单规范”要解决的问题。

Sample=(Name,{label1:v1,⋯ ,labeln:vn},Value,Timestamp)\displaystyle Sample = (Name, \{label_1: v_1, \cdots, label_n: v_n\}, Value, Timestamp)
公式说明:一个样本由指标名、标签集合、值和时间戳组成,四者缺一不可。
  1. 样本(Sample)一次测量结果的最小单位,就像体检单上一个“项目名 + 数值 + 时间”填满的格子。
    SampleSample
  2. 名称与标签集$(Name, \{label_1: v_1, \cdots, label_n: v_n\})$,指标名像项目名,标签集合像被检人信息,共同定位“谁在什么维度上的指标”。
    (Name,{label1:v1,⋯ ,labeln:vn})(Name, \{label_1: v_1, \cdots, label_n: v_n\})
  3. 值与时间戳$Value$ 是检测数值,$Timestamp$ 是测量时刻;同一指标同标签下,不同时间戳构成一条时间序列。
    Value,TimestampValue, Timestamp

格式规范

统一模板印刷好了,但护士的字迹五花八门:有人写“120/80“,有人写”血压正常“,还有人画了个箭头。总检医生再专业也吃不消。所以体检中心规定:每个格子只能填规定格式的数字,且必须附带说明这一行是什么。OpenMetrics 的 Exposition 格式就是这份”书写规范”。

Exposition(呈现)格式规定了指标在 HTTP 响应体里如何以纯文本呈现。最核心的是三类行:HELP 行(# HELP 指标名 帮助文本)、TYPE 行(# TYPE 指标名 类型),以及样本行(指标名{标签} 值 [时间戳])。文本以 # EOF 结束,表示“报告单到此为止”。

一个经典输出长这样:# HELP http_requests_total 累计请求数、# TYPE http_requests_total counter、http_requests_total{code="200"} 1024。标签值中的反斜杠、双引号、换行符都需要转义;Content-Type 协商让 Prometheus 知道收到的是 0.0.4 兼容文本还是 OpenMetrics 1.0 文本。任何语言实现的 HTTP 服务,只要输出符合这个文本协议,就能被标准采集器读取。

填单规范一统一,护士们不再各写各的,总检医生手里的每份报告都是同一种笔迹。有了统一格式,接下来我们该造一台“自动填单的体检仪器”——自定义 Exporter。

sample_line=name{label1="v1",label2="v2",⋯ } value [timestamp]\displaystyle sample\_line = name\{label_1="v_1", label_2="v_2", \cdots\} \ value\ [timestamp]
公式说明:文本协议中每个样本行的标准语法,标签用花括号包裹,时间戳为可选项。
  1. 指标名与标签$name\{label_1="v_1", label_2="v_2", \cdots\}$ 精确定位一条时间序列,标签值必须用双引号包裹。
    name{label1="v1",label2="v2",⋯ }name\{label_1="v_1", label_2="v_2", \cdots\}
  2. 值(value)紧跟在标签后的数值,对应体检格子里的测量结果。
    valuevalue
  3. 时间戳([timestamp])方括号表示可省略;省略时采集系统以抓取时刻作为该样本的时间。
    [timestamp][timestamp]

Exporter 开发

体检中心里,测血压靠血压计,测体温靠体温计。每台仪器只做一件事:从人体采集一种生理信号,再按统一格式把它印到体检单上。在监控世界里,Exporter 就是这样的体检仪器。

Exporter 的职责可以拆成三段:采集(Collect)、标准化(Normalize)、暴露(Expose)。采集是从目标应用中读取状态;标准化是整理成 OpenMetrics 规定的样本结构;暴露是以 HTTP 端点的形式把文本输出出去。三段加起来,就是一个合格的 Exporter。

开发自定义 Exporter 时,多数语言都有官方客户端库,Python 的 prometheus_client 是最常用的一种。核心流程:定义指标对象(如 Counter('http_requests_total', '计数帮助'))、在采集回调中更新值、注册到默认注册表、启动 HTTP 服务在 /metrics 暴露。类型选择有讲究:只增不减用 Counter,可增可减用 Gauge,要分析位数分布用 Histogram 或 Summary。

血压计、体温计各有分工,但共同点是都按同一张体检单填数。自定义 Exporter 只要遵循采集-标准化-暴露三段式,无论监控的是进程、数据库还是 AI 模型服务,Prometheus 都能一视同仁地收走数据。仪器造好了,下一节该让总检医生与它约定工作节奏。

Exporter≜Collect(App State)→Normalize(Samples)→Expose(HTTP)\displaystyle Exporter \triangleq Collect(App\ State) \to Normalize(Samples) \to Expose(HTTP)
公式说明:Exporter 等价于“采集状态、标准化样本、HTTP 暴露”三个动作的串联管道。
  1. 采集(Collect)从目标应用读取原始状态,比如读取健康指标、数据库连接数或模型推理耗时。
    Collect(App State)Collect(App\ State)
  2. 标准化(Normalize)把采集结果整理成 OpenMetrics 规定的样本结构和文本格式。
    Normalize(Samples)Normalize(Samples)
  3. 暴露(Expose)通过 HTTP 服务在指定路径(默认 /metrics)对外输出文本,供采集端读取。
    Expose(HTTP)Expose(HTTP)

集成实践

总检医生不会 24 小时守在每台仪器旁边,而是定好时间表:每天早晨 8 点整来体检中心收报告,每份报告必须在 5 分钟内交出来,交不出的算超时。这个节奏,就是 Prometheus 的抓取周期。

Prometheus 通过配置文件 prometheus.yml 中的 scrape_configs 来定义抓取任务。每个 job 可以配置:job_name(任务名)、scrape_interval(抓取间隔,如 15s)、scrape_timeout(抓取超时,如 10s)、metrics_path(指标路径,默认 /metrics)、static_configs(静态目标列表)或服务发现配置。

抓取生命周期是这样的:Prometheus 根据目标列表,周期性发起 HTTP GET 请求到 <target>:<port>/metrics,读取响应体文本,按 OpenMetrics 格式解析后写入时序数据库。超时配置有一条黄金法则:抓取超时必须小于抓取间隔,否则上一次抓取还没结束,下一次就开始了,形成积压雪崩。

时间表约定好后,总检医生每天准时收单,仪器们各就各位。但体检高峰季来了:成百上千台仪器同时出报告,总检医生和仪器都开始吃力。怎么让整套流程既快又不互相拖累?这就是性能优化要解决的问题。

scrape_timeout<scrape_interval\displaystyle scrape\_timeout < scrape\_interval
公式说明:单次抓取的超时上限必须严格小于抓取周期,这是防止抓取任务重叠积压的基本约束。
  1. 抓取超时(scrape_timeout)单次抓取允许的最大等待时间,像收单的“截止时间”,超时则本次作废。
    scrape_timeoutscrape\_timeout
  2. 抓取周期(scrape_interval)相邻两次抓取的间隔,像医生的查房频率。
    scrape_intervalscrape\_interval
  3. 严格小于(<)截止时间必须早于下一次查房开始,否则上一次还没收完、下一次又来,报告会越积越多。
    <<

性能优化

体检高峰季,上百人被安排在同一天。如果每台仪器都磨磨蹭蹭,下一位体检者就会被无限延后;如果几十台仪器同时测量,又可能把体检者折腾得受不了。聪明的体检中心会做三件事:给每台仪器设定单人的时间上限、错峰并行测量、把常测结果缓存下来复用。

Exporter 的性能优化同样围绕三个方向。一是超时控制:用 Context 给每次采集设置超时,目标应用无响应时快速放弃,避免线程堆积。二是并发采集:内部用信号量(Semaphore)限制并发数,既能并行提升速度,又不会打爆目标应用。三是指标缓存:对代价高的采集结果做短时间缓存,避免每次抓取都重复计算。

还有一个容易被忽略的优化点——降低基数(Cardinality)。指标基数等于各标签取值数的乘积。如果一个标签是 user_id,有 100 万用户,那么这个指标瞬间膨胀成 100 万条时间序列,存储和查询都会雪崩。经验法则是:标签只放取值有限的维度(如 method、status_code),不放无限维度(如 user_id、request_ip)。

经过提速增效,体检中心在高峰季依然秩序井然:超时上限防住慢仪器,并发策略平衡负载,缓存减少重复劳动,而标签设计避免了报告单无限膨胀。仪器状态越来越好,但别忘了:新仪器上岗前,还得先通过校准。

Cardinality=∏l∈Labels∣Dl∣\displaystyle Cardinality = \prod_{l \in Labels} |D_l|
公式说明:时间序列总数等于所有标签取值数量(维度基数)的乘积,标签越多、取值越杂,膨胀越剧烈。
  1. 基数(Cardinality)一个指标在所有标签组合下展开出的时间序列条数。
    CardinalityCardinality
  2. 标签集合(Labels)$l \in Labels$ 遍历指标上的全部标签维度。
    l∈Labelsl \in Labels
  3. 乘积(\prod)$|D_l|$ 表示每个标签的取值个数,全部相乘就是总序列数。三个取值 10 的标签相乘即 1000 条序列。
    ∏l∈Labels∣Dl∣\prod_{l \in Labels} |D_l|

测试调试

新买的血压计不能直接上岗。工程师先用标准水银柱对比读数,再让护士连续测三次确认稳定,最后在真实体检中抽查几份报告,确认打印格式无误。这套“校准”流程,对应到 Exporter 就是测试与调试。

测试 Exporter 通常分四步走。第一步单元测试:用客户端库的测试工具直接断言指标值是否符合预期。第二步 curl 验证:手动请求 http://localhost:9100/metrics,肉眼检查输出行的格式。第三步格式检查:用 promtool check metrics 自动校验指标命名、类型、格式是否合规。第四步日志排查:开启 Exporter 的调试日志,观察采集耗时和错误信息。

用 prometheus_client 写单元测试时,可以用 generate_latest() 拿到最新文本,再断言其中是否包含期望的指标行。curl 是快速验证的利器:curl -i http://localhost:9100/metrics 能看到状态码和 Content-Type,curl -s ... | head 能查看前几行。promtool 则是格式规范的最终裁判,它会告诉你哪一行标签转义不对、哪个指标名不合规。

校准通过的仪器才能放心交到护士手里。至此,你手里已经有了一台符合 OpenMetrics 标准、经过测试校准的体检仪器,也知道总检医生如何与它协同。从一张体检单开始,到一整套体检流程跑通——这就是 OpenMetrics 标准化与 Exporter 开发实战的全部脉络。

valid  ⟺  format_ok∧type_ok∧value_ok\displaystyle valid \iff format\_ok \land type\_ok \land value\_ok
公式说明:一个 Exporter 输出合格,当且仅当格式合法、类型声明正确、数值含义合理三者同时成立。
  1. 合格(valid)Exporter 输出可以被 Prometheus 正确解析并可靠使用的状态。
    validvalid
  2. 格式与类型(format\_ok \land type\_ok)文本语法正确,且 TYPE 声明的类型与数值行为一致。
    format_ok∧type_okformat\_ok \land type\_ok
  3. 数值合理(value\_ok)数值在业务上合理,比如 Counter 不减、Gauge 范围正确。
    value_okvalue\_ok

AI 应用场景

电商大促业务自定义指标监控

阶段:数据采集与预处理

解决的问题:业务团队需要下单量、支付耗时等自定义指标,传统埋点散乱、格式各异,告警无统一入口。用 OpenMetrics 标准 + 自定义 Exporter 统一采集,让业务指标与系统指标进入同一套监控体系。

具体案例:电商后端用 Python 实现一个自定义 Exporter,暴露 order_created_total 和 payment_duration_seconds 两个指标,挂在:9100 端口。Prometheus 每 15 秒抓取一次,Grafana 大屏实时展示大促进度,SRE 按 _total 后缀自动识别 Counter 并配置增量告警。

数据库与中间件指标快速接入

阶段:特征工程与监控数据整合

解决的问题:MySQL、Redis 自带状态命令但无统一输出格式,手工解析成本高且易错。社区成熟的 Exporter(mysqld_exporter、redis_exporter)已经按 OpenMetrics 规范输出,开箱即用,节省大量开发时间。

具体案例:SRE 在 Kubernetes 集群中为每个 MySQL Pod 部署边车模式(Sidecar)的 mysqld_exporter,通过服务发现自动注册到 Prometheus,无需手动维护目标列表。新扩容的数据库实例上线即被自动纳入监控。

AI 模型服务在线监控

阶段:模型服务部署与在线监控

解决的问题:推理服务的 QPS、响应延迟、GPU 利用率等指标需要统一可视化和告警。用自定义 Exporter 按 OpenMetrics 格式暴露推理指标,可无缝接入 Prometheus 生态。

具体案例:MLOps 团队在推理服务旁挂一个自定义 Exporter,暴露 inference_requests_total(Counter)和 inference_latency_seconds(Histogram),并按模型版本打标签。当 p99 延迟超过阈值时,Prometheus 告警自动触发模型回滚流程。

Python 演示

python53 行
"""模拟一个标准库实现的自定义 Exporter 演示运行后访问 http://127.0.0.1:9100/metrics 查看指标"""import randomimport timefrom http.server import BaseHTTPRequestHandler, HTTPServerfrom threading import Thread METRICS = {    "http_requests_total": {"type": "counter", "help": "累计处理的 HTTP 请求数", "value": 0},    "http_request_duration_seconds": {"type": "gauge", "help": "最近一次请求耗时", "value": 0.0},}  def render_metrics():    lines = []    for name, info in METRICS.items():        lines.append("# HELP {} {}".format(name, info["help"]))        lines.append("# TYPE {} {}".format(name, info["type"]))        lines.append("{} {}".format(name, info["value"]))    lines.append("# EOF")    return "\n".join(lines)  class MetricsHandler(BaseHTTPRequestHandler):    def do_GET(self):        if self.path == "/metrics":            body = render_metrics().encode()            self.send_response(200)            self.send_header("Content-Type", "text/plain; version=0.0.4")            self.send_header("Content-Length", str(len(body)))            self.end_headers()            self.wfile.write(body)        else:            self.send_response(404)            self.end_headers()     def log_message(self, fmt, *args):        pass  def simulate_traffic():    while True:        METRICS["http_requests_total"]["value"] += 1        METRICS["http_request_duration_seconds"]["value"] = round(random.uniform(0.01, 0.5), 3)        time.sleep(0.5)  if __name__ == "__main__":    Thread(target=simulate_traffic, daemon=True).start()    server = HTTPServer(("127.0.0.1", 9100), MetricsHandler)    print("exporter is running at http://127.0.0.1:9100/metrics")    server.serve_forever()
目的:用纯 Python 标准库实现一个迷你 Exporter,模拟请求计数和耗时指标的采集与 HTTP 暴露,演示 OpenMetrics 文本格式的完整输出。
  1. METRICS = {...}用字典作为指标仓库,记录每个指标的类型、帮助文本和当前值,这是“体检单”的数据来源。
  2. lines.append("# HELP {} {}".format(...))输出 HELP 行,向采集端说明这个指标的含义。
  3. lines.append("# TYPE {} {}".format(...))输出 TYPE 行,声明指标类型(counter/gauge),这是格式规范的核心。
  4. if self.path == "/metrics":只有访问 /metrics 路径才返回指标文本,其余路径返回 404。
  5. self.send_header("Content-Type", "text/plain; version=0.0.4")声明响应体为 0.0.4 兼容格式,Prometheus 据此解析。
  6. Thread(target=simulate_traffic, daemon=True).start()启动后台线程模拟业务流量,让指标值持续变化,便于观察。

常见误区

误区只要给指标加上 `_total` 后缀,它就是一个 Counter。比如把当前在线人数命名为 `online_users_total`,然后在 TYPE 行声明为 gauge。

正解_total 后缀是 Counter 的命名约定,但决定类型的是 # TYPE 行与数值行为。在线人数可增可减,应命名为 online_users 并声明为 gauge。就像体检单上的“体温”格子不能因为想省事就填成“身高”的写法。

为何常见:初学者刚接触命名规范时,容易把“后缀规则”误解为“加后缀即类型”,忽略了类型声明与数值语义的一致性。

误区不用 prometheus_client 或 client_golang 写出来的就不是正规 Exporter,Prometheus 不会认。

正解OpenMetrics 的核心是文本协议。任何 HTTP 服务,只要输出符合规范的文本(HELP/TYPE/样本行/EOF),Prometheus 都能采集。官方客户端库只是帮你省事,不是唯一通道——就像体检单只要能填对格式,用钢笔还是圆珠笔并不重要。

为何常见:教程大多基于官方库演示,导致初学者把“开发工具”当成“准入资格”,忽略了标准本身。

误区抓取越慢越容易超时,那把 scrape_timeout 设置成比 scrape_interval 大,不就安全了吗?

正解超时大于间隔会导致抓取任务重叠:上一次还没结束,下一次已经启动,最终造成并发堆积和资源耗尽。正确做法是超时严格小于间隔,例如间隔 15s 配超时 10s。这就像收单截止时间不能晚于下一次查房开始时间。

为何常见:直觉上“更大更宽松”看似安全,但抓取系统是周期性任务模型,重叠才是灾难。

误区为了监控更细,把 user_id、request_ip、session_id 这些都加进标签,这样每个用户都能单独看指标,多好。

正解标签值是无限增长的高基数维度时,时间序列数量会按乘积爆炸,直接拖垮存储和查询。合理做法是只保留取值有限的维度(method、status_code、instance),真正需要按用户分析时走日志系统。

为何常见:从“业务粒度”出发而非从“系统容量”出发思考标签设计,是监控新人最容易踩的坑。

误区`curl` 能返回指标文本、状态码也是 200,说明 Exporter 已经写好了,不用再做别的检查。

正解curl 只能证明“有响应”,不能证明格式完全合规。标签转义错误、TYPE 行缺失或类型声明错误,都可能导致 Prometheus 解析失败或告警误判。必须再用 promtool check metrics 做自动校验,就像仪器校准不能只靠看一眼刻度。

为何常见:能返回数据给了人“已经成功”的错觉,而格式合规性的验证需要额外工具和耐心,容易被跳过。

面试题

Q1. 下列哪项是 OpenMetrics 中 Counter 指标的核心特征?

单选题 · easy

  • A.只能增加不能减少← 正确答案
  • B.可以增加也可以减少
  • C.只能表示瞬时状态
  • D.只能记录字符串值

答案:A。Counter 用于累计事件次数,数值只增不减,进程重启后可从 0 重新累计,适合记录请求总数这类指标。Gauge 才可增可减。就像体检中心的“累计接待人数”计数器,只会往上加。

Q2. 指标名 http_requests_total 中 _total 后缀的作用是什么?

单选题 · easy

  • A.表示该指标有总量上限
  • B.暗示该指标是 Counter 类型← 正确答案
  • C.表示该指标包含时间戳
  • D.表示该指标支持多标签

答案:B。命名规范约定 Counter 类型指标使用 _total 后缀,方便 PromQL 中自动识别并可配合 rate() 计算速率。但实际类型仍以 TYPE 行为准。就像体检单上的项目名含“累计”字样,帮助人快速理解含义。

Q3. 从应用状态转换到可被 Prometheus 抓取的文本格式,由哪个组件完成?

单选题 · easy

  • A.Prometheus 服务器
  • B.目标应用自身
  • C.Exporter 程序← 正确答案
  • D.Grafana 面板

答案:C。Exporter 负责采集应用状态、标准化为 OpenMetrics 文本并通过 HTTP 暴露。Prometheus 只负责按周期抓取与存储。就像血压计负责测量并把数值印在单子上,总检医生只管收单。

Q4. OpenMetrics 文本格式中 TYPE 行的作用是什么?

单选题 · mid

  • A.声明指标值的类型
  • B.声明指标名与指标类型← 正确答案
  • C.声明标签键值集合
  • D.声明时间戳的格式

答案:B。# TYPE 指标名 类型 声明该指标属于 counter、gauge、histogram 等哪一类,采集端据此决定数值的解释方式。A 是混淆项,TYPE 声明的是指标类型而非数据类型的数值格式。

Q5. 在 prometheus.yml 中用哪个配置块定义抓取任务?

单选题 · mid

  • A.告警规则配置
  • B.抓取配置区← 正确答案
  • C.存储保留配置
  • D.查询规则配置

答案:B。scrape_configs 是 Prometheus 中定义抓取任务的核心配置块,包含 job_name、scrape_interval、scrape_timeout、metrics_path 以及目标列表。告警规则在 rules 中定义,存储保留在 storage 中配置。

Q6. 关于抓取超时与抓取间隔的关系,正确的是?

单选题 · mid

  • A.超时必须大于间隔
  • B.超时必须小于间隔← 正确答案
  • C.两者必须完全相等
  • D.两者没有任何关系

答案:B。若 scrape_timeout 大于 scrape_interval,前一次抓取尚未结束、下一次抓取就启动,形成任务重叠与资源堆积。正确配置是超时小于间隔,例如间隔 15s 配超时 10s。

Q7. 指标基数(Cardinality)过高的主要风险是什么?

单选题 · mid

  • A.应用 CPU 使用率下降
  • B.存储与查询性能降级← 正确答案
  • C.指标无法暴露为文本
  • D.网络带宽持续提升

答案:B。基数过高意味着时间序列数量爆炸,会拖垮 Prometheus 的存储、查询和告警计算。应避免 user_id、ip 等高基数标签,只保留取值范围有限的维度。

Q8. 下列哪些属于 OpenMetrics 标准的指标类型?

多选题 · mid

  • A.计数器型← 正确答案
  • B.摘要型← 正确答案
  • C.桶结构型
  • D.信息型← 正确答案

答案:ABD。OpenMetrics 标准类型包括 Counter(计数器)、Gauge、Histogram、Summary(摘要)、Info(信息)、StateSet。Bucket(桶)是 Histogram 内部的概念,不是独立指标类型。

Q9. 开发自定义 Exporter 时,合理的性能优化手段有哪些?

多选题 · hard

  • A.用 Context 设置采集超时← 正确答案
  • B.高频指标并发抓取← 正确答案
  • C.无条件全量采集所有指标
  • D.对采集结果使用缓存复用← 正确答案

答案:ABD。Context 超时防止卡死,并发采集提升吞吐但需限流,缓存减少重复计算。C 恰恰相反,无条件全量采集会导致性能恶化,应结合业务需求精简采集项。

Q10. 测试与调试 Exporter 时,常用的手段包括哪些?

多选题 · hard

  • A.curl 验证暴露输出← 正确答案
  • B.promtool 检查格式← 正确答案
  • C.日志打印采集耗时← 正确答案
  • D.修改 Prometheus 源码

答案:ABC。curl 验证响应内容、promtool 校验格式合规、日志排查采集耗时是三类标准手段。D 没有解决 Exporter 自身问题,而且修改监控系统源码成本极高、与实际排查目标无关。