实测 Prometheus 抓取模型:相邻样本间隔偏差只有几毫秒;抓取失败或序列消失 1.9 s 后即时查询就查不到,带显式时间戳的样本要等 lookback-delta(这里 29.9 s);响应超过 scrape_timeout 的抓取整次失败;活 2 s 的批处理任务 20 个里只有 1 个被抓到。
实测 rate / increase / irate:稀疏事件的 increase 在真实值 3 附近波动(2.18 到 3.27);窗口等于抓取间隔时 rate 没有结果;irate 的取值范围 0.0 到 400.0 而 rate 是 80.0 到 160.0;抓取空窗里崩溃会永久丢掉 200 个增量,重启后涨得比崩溃前还快时 Prometheus 把 300 个新增只算成 100。
实测 RED 与 USE:同一个 8 线程服务的四种问题在不同指标上露出来——错误率升高只改变错误率(17.7%),下游变慢让平均耗时从 26 ms 升到 67 ms,过载让线程利用率 100%、队列满、拒绝 293/s、错误率 48.8%;把 404 也算错误会让错误率从 5.0% 变成 30.1%。
实测 SLO 与错误预算:99.9% 的 30 天预算是 43.2 分钟;在一个 SLO 99%、300 s 预算窗口的模拟里,6 s 的 30% 失败消耗了 61% 的预算,60 s 的 3% 失败再消耗 60%;快燃烧只发现了前者,慢燃烧发现后者时预算已经用到 104%。
实测告警:for: 15s 只在持续异常 69 s 时通知一次,for: 0s 对短暂异常是否通知取决于和 Alertmanager 计时的相位(三次里只通知了一次);keep_firing_for 把相隔 9 s 的三次短暂异常合成一个告警;按 alertname 分组 20 个告警 1 条通知,加 inst 则 20 条;repeat_interval 30 s 的重复通知实际在 36.3 s 之后;被抑制和被静默的告警通知数为 0。
实测结构化日志与 trace_id:20 万行里文本日志用正则提取 user 错了 3898 行而 JSON 为 0,但 JSON 体积更大(34.6 对 21.2 MB);span 结束后和没传上下文的线程池里的日志 0% 带 trace_id;Collector 的 filelog + trace_parser 把 trace_id 提升到 OTLP 的 traceId 字段;10% 采样时日志里 1000 个 trace_id 只有 76 个能找到对应的 trace。
实测可观测性开销:Go 里不带标签的 Prometheus Counter.Inc() 3.9 ns、查标签的 35.1 ns、一行 slog 约 596 ns;Python 里一个 span 约 9 µs、一行日志写文件 8.8 µs;3 ms 的慢日志目的地让同步写的每次调用多 4.5 ms,异步队列只要 0.117 ms 但在 8 ms 目的地下丢了 66 行;1 ms 的请求加上指标、日志和 span 多出 52 µs(5.2%)。
实测数据库追踪:SQL 注释里放 traceparent 让 120 条慢日志全部唯一对应到调用链(不带注释只有 14 条能唯一对应);performance_schema 按 trace_id 找回 30 / 30 条快查询;N+1 每个请求 21 个 db span、p50 2.19 ms 而 JOIN 0.79 ms;db.statement 写字面值有 1000 个不同语句且含 1000 个邮箱;连接池等待让一个 db span 的中位数是 507 ms(数据库只用 203 ms)。
实测错误追踪:500 层调用的异常堆栈文本是 62421 字节、格式化 13257 µs(limit=-20 只剩 2665 字节);用原始消息分组 1 万个异常得到 10000 个组,类型 + 最内层 2 帧正好分成 5 个组;同一个 bug 爆发 2 万次时全量捕获耗 CPU 18.43 s、限流加计数器只要 0.07 s;线程池任务的异常不取结果就悄悄丢了。
实测服务依赖图:Collector 的 servicegraph 连接器在 span 全部送达时与真实调用次数完全一致,数据库、外部服务、消息变成虚拟节点,根 span 被记成 user → frontend;丢 20% 服务端 span 时 frontend → orders 少 411 次,同时 frontend → unknown 多 411 次;10% 采样时每条边只有真实调用的 10.3%~11.1%。
自己写了一个 57 行的最小 trace 收集器(OTLP/HTTP 解析 + SQLite):与 SDK 里的 12194 个真实 span 逐个对得上;逐个提交只有 2,833 span/秒,按请求批量写是 17 万 span/秒;按 trace_id 加索引后查一个 trace 从 22.2 ms 降到 0.009 ms;丢 5% 的 span 会让 21.1% 的 trace 残缺。
实测时序数据编码:我按 Gorilla 论文写的编码器能无损还原,恒定值 0.26 字节/样本、计数器约 1.9~2.0、随机游走的浮点 gauge 7.83;Prometheus 3.15.0 真实存下的 chunk 平均 4.43 字节/样本(我的编码器 3.74),index 每条序列约 109 字节;真实抓取的时间戳有毫秒级抖动,时间戳要 6.51 位/样本。