Skip to content

健康与自观测

agent 对账结果与 agent 自身运行指标的落库层,回答两个问题:该节点是否已收敛至期望世代,以及 agent 进程自身运行是否正常。

粒度保留
node_statusL2节点覆盖式 upsert
node_status_eventsL2节点 × 上报事件每 (节点, 种类) 100 条
node_metrics_rollupL3节点 × 5 min 桶60 天
node_metrics_lastL2节点覆盖式 upsert

模型定义在 app/db/models/node_status.pymetrics.py。上报节奏约 5 min,摄入策略见写入路径;读侧的聚合结果有一层 L5 缓存(health:*,TTL 10 秒),见 KV 与缓存键索引

本册的四张表两两成对:node_status 为当下态,node_status_events 为最近数小时的历史;node_metrics_last 为差分基准,node_metrics_rollup 为 60 天的降采样曲线。事件历史窗口仅约 8 小时,更长的观测窗口依赖 rollup——这是自观测存档存在的唯一理由。


node_status

每节点最新运行时健康,随上报 upsert。

类型约束 / 默认说明
node_idString(64)PK,FK→nodes.node_id(CASCADE)主键即外键
desired_generationInteger可空控制面已发布的期望世代
observed_generationInteger可空agent 实际观测到的世代
last_report_statusString(32)可空最近对账状态(succeeded / degraded / failed / skipped
last_apply_statusString(32)可空最近 apply 状态
drift_countIntegerNOT NULL,默认 0漂移计数(仅由 kind=report 事件的 payload.drift 长度给出)
healthString(16)NOT NULL,默认 unknown派生健康。库里只落四态ok / degraded / stale / unknown;第五态 down 是读侧按时间阈值叠加的覆盖,不改库
last_snapshot / last_report / last_applyJSON可空最近一次完整 payload(界面下钻用)
bgp_summaryJSON可空快照摄入时预提取的 payload.bgp_protocols 原样副本
peer_ratesJSON可空与上一份快照差分得出的 per-peer 速率(摄入时预提取)
last_snapshot_at / last_report_at / last_apply_atDateTime(tz)可空对应时刻
updated_atDateTime(tz)server_default now,带 onupdate更新时刻

健康五态的判定顺序见 Control Server 内部

该表仅 10 行却存有三份完整 payload,实测 336 kB,主要体积在 TOAST[1] 中。bgp_summarypeer_rates预提取列:若不预提取,每次 fleet 聚合都需将 last_snapshot 整份取出并解析。

这两列尚未纳入迁移链,缺列时读侧自动回退到解析完整快照的慢路径。见已知偏差


node_status_events

append-only 上报历史。写入后按 (节点, 种类) 各保留最近 100 条裁剪(_HISTORY_KEEPservices/node_status.py)。四种 kind × 10 节点即上限 4 000 行(实测 3 740),约覆盖 8 小时。

类型约束 / 默认说明
idIntegerPK,autoincrement主键
node_idString(64)FK→nodes.node_id(CASCADE),NOT NULL,index所属节点
kindString(16)NOT NULL,indexsnapshot / report / apply / reresolve(WG endpoint 重解析)
generationInteger可空关联世代
statusString(32)可空状态
payloadJSONNOT NULL完整上报 payload
created_atDateTime(tz)server_default now,index写入时刻

提示: ix_node_status_events_created_at(712 kB)实测从未被使用,见索引清单


node_metrics_rollup

agent 自观测(self_metrics)的 5 min 降采样存档,是 GET /ui/nodes/metrics 机群指标矩阵的数据层。随快照入库累加;旧版 agent 的快照不带 self_metrics 则 no-op。

通用形态(桶、sum + count、保留期、分区门控)见时序建模通则

类型约束 / 默认说明
node_idString(64)PK(复合),FK→nodes.node_id(CASCADE)所属节点
bucket_startBigIntegerPK(复合)桶起点(epoch 秒,对齐 5 min)
cpu_sum / cpu_countFloat / IntegerNOT NULL,默认 0CPU 百分比的和与计数,均值 = 和 / 计数
rss_sum / rss_countFloat / IntegerNOT NULL,默认 0RSS(MB)的和与计数
reconcile_failuresIntegerNOT NULL,默认 0桶内 reconcile 失败次数(累计计数与 prev 差分后累加;agent 重启归零时按当前值计)
sample_countIntegerNOT NULL,默认 0落桶快照数(>0 即「该桶有上报」)
updated_atDateTime(tz)server_default now,带 onupdate更新时刻

提示:cpu_count / rss_countsample_count 分列,是因为自观测字段全部可选,一份快照可能仅携带其中一项。共用同一计数会使缺字段的桶算出偏低的均值。

node_metrics_last

每节点最近一次采样时刻与累计失败数,是 reconcile_failures 差分的持久基准,取值仅向前推进。

类型说明
node_idString(64)PK,FK→nodes.node_id(CASCADE)
captured_atString(64)最近一次采样时刻(ISO 8601 原文)
total_failuresBigInteger累计失败数
updated_atDateTime(tz)更新时刻

  1. TOAST(The Oversized-Attribute Storage Technique):PostgreSQL 对超过约 2 kB 的大字段的存储机制,将其压缩后移出主表、存入关联的 TOAST 表。因此含大 JSON 列的表,主表行数虽少,pg_total_relation_size 仍可能显著偏大。 ↩︎