遥测接入实验(U64)
单模块 Maven 工程(Boot 4.0.9 parent/BOM,JDK 21)+ 两个官方发行版二进制(OpenTelemetry Collector core 0.164.0、Prometheus 3.15.1,本机直接运行,不用 Docker)。回答一个组合问题:指标、追踪、采样、Context、Collector 管道接起来之后,一次真实故障怎么从信号定位到原因。
从仓库根运行完整公开入口:
实验代码bash
python3 labs/telemetry/run.py需要 JDK 21、Maven 3.9.9、Python 3。二进制位于仓库外缓存 ~/.cache/software-engineering-study/java-depth-impl/u64/bin/(首次缺失时从官方 release 下载并记录 SHA-256);原始日志在 ~/.cache/software-engineering-study/java-depth-impl/u64/runtime/<run>/,短产物为 evidence/u64-2026-10-28.json。所有进程(app/collector/prometheus/mock)由入口启动并 terminate 回收,强杀视为失败;只使用 127.0.0.1 与随机端口。
实验拓扑
text
Boot 服务(真实 jar,/actuator/prometheus + OTLP traces)
├─ Prometheus(3.15.1) --直抓--> /actuator/prometheus(对照组)
└─ otelcol(0.164.0)
├─ prometheus receiver 抓 /actuator/prometheus → prometheus exporter(随机端口)
└─ otlp http receiver(随机端口)→ file exporter(traces.json 落盘)
Prometheus 查询 Collector 的 prometheus exporter(job=collector/exported_job=telemetry-lab)所有端口由 run.py 每次运行随机分配,记录在 evidence 的 ports 字段。
20 项断言
| 组 | 断言 | 关键观察 |
|---|---|---|
| 指标语义 | counter 累计、timer 桶、gauge 当前值、MeterFilter 拒绝 | counterCumulative / gaugeReflectsCurrent / filterDeniesTags(单测,3 行) |
| 请求与基数 | 12 次订单成功、高基数标签被拒 | orders-success=12、highcard-filtered lab_highcard series=0 |
| Context | 裸线程池空 traceId、包装池一致 | context-propagation plainEmpty=True wrappedMatches=True |
| PromQL | rate、sum、histogram_quantile、无数据空向量 | promql-rate-via-collector、collector-scraped-total=12.0、histogram-quantile p50=…、promql-no-data |
| 追踪 | probability=1.0 导出 server span、resource 正确;0.0 零新增 | otlp-traces-exported serverSpans=…、otel-resource service.name=['telemetry-lab']、sampling-zero-blindspot before=after |
| 排障链 | mock --fail 注入 → 502 → rejected 计数 → PromQL 速率 → 502 span + 日志 | downstream-failure-502 [502,502,502,502]、rejected-counter=4.0、promql-rejected-rate、troubleshoot-chain errorSpans=4 rejectLogLines=4 |
| 断连 | Collector 停止后应用照常服务 | export-failure-does-not-block elapsed<2s |
两个必须知道的实测细节
- prometheus receiver 默认抓
/metrics,Boot 是/actuator/prometheus——metrics_path必须显式指向后者。 - 经 Collector 转发后
job变为 collector 的 job,原始 job/instance 挪到exported_job/exported_instance(honor_labels 语义);PromQL 选择器要写{job="collector",exported_job="telemetry-lab"}。
未运行
Prometheus HA/长期存储(Thanos/Mimir)、Grafana 与告警路由、Tempo/Jaeger、Loki/ELK、Kubernetes、TLS/mTLS、Collector contrib、跨主机时钟偏差、容量压测(U81)。详见 evidence 的 limits。