附录 B:练习参考与继续实验
B.1 证据模型与系统边界
第 1 章可以提出“入口只表示已接受,异步消费尚未完成”与“消费已完成,但统计读模型尚未更新”两个竞争假设。先检查实际业务完成标记,再检查消息处理事件或下游读模型。若完成标记存在而界面未更新,就不应继续把原因固定为消息没有消费。
第 2 章中,Collector 接口可连与 up=1 仍不能证明 Java SDK 发出了 trace,也不能证明 traces pipeline 引用了正确 exporter。需要提交实际请求取得 ID,再查询 Tempo。若只抓取到了 Collector 自身或空的业务序列,Prometheus 可用也无法替代业务数据验证。
第 3 章中,父 span 结束之后子工作仍可继续,时间重叠不是父子关系的唯一条件。长期消息任务或多输入聚合可以考虑 link。关键是描述因果来源,并让模型与所用消息框架的语义保持一致。
B.2 传播与依赖观察
第 4 章的错误顺序是先注入当前入口上下文,再创建 HTTP client span。此时远端继承的是入口 span ID。业务 JSON 与 HTTP 调用本身可以完全正确,所以普通功能测试不会发现该仪表化缺陷。
第 5 章的等待可能来自连接池、应用调度、网络往返和 Redis 执行。服务端命令统计或慢日志有助于区分服务执行时间,连接池等待指标或线程证据有助于定位本地争用。命令前的 Thread.sleep 被包在 client span 内,所以它不是 Redis 服务端延迟。
第 6 章的多来源工作可以在新 span 上添加十个来源上下文的 link,而不是把十个 ID 拼成一个非法或无语义的新身份。新的 span 仍有自己的 trace/span ID,link 保存来源关系。批量结果和重试次数也应作为另外的信息记录。
第 7 章的日志 span ID 不在后端,可能是 span 尚未结束或尚未导出,可能是未采样或已过期,也可能是在错误 Scope 中读取身份。需要把 sampled 标志、查询窗口、导出状态和日志发生位置一起检查。
B.3 指标、查询与采样
第 8 章总错误数是 10 加 5,即 15;总请求数 1010,所以错误比例约 1.485%,并非 25.5%。高流量实例应该获得与其请求量相符的权重。trace ID 若作为普通标签,会把序列数量推向请求数量级;exemplar 则只保存受限的关联样本。
第 9 章可以依次检查 SDK metric reader、OTLP receiver、metrics pipeline 引用、Prometheus exporter、抓取目标与查询标签。使用错误的 service_name 或仅查看过窄窗口,也可能让存在的数据看起来像丢失。
第 10 章不能把 500、450 和 800 相加。订单 server 很可能位于网关等待范围内,消费者也可能跨过 HTTP 返回继续工作。需要开始、结束时间与依赖关系,才能确定用户关键路径。
第 11 章头部 1% 采样在知道结果前作出决定,不能保证后来出错的请求完整保留。尾采样需要保存待决数据,并使同一 trace 的相关 span 到达能够共同决策的位置;容量与路由都要验证。
B.4 成本、告警与故障恢复
第 12 章可以选择 route、outcome、service 三类有限维度,按已部署服务与路由数量估计上限。具体订单调查由 trace/log 的受控字段完成,指标到 trace 的跳转可以使用 exemplar。估计后还要查询实际序列,检查资源自动转换是否带入新维度。
第 13 章目标为 99.9% 时,允许错误比例是 0.1%,5% 错误对应 burn rate 50。入口接受成功没有覆盖排队与消费完成,因此不能保证异步一分钟目标。异步 SLI 应有自己的起点、终点、失败和超时定义。
第 14 章可先明确用户等待的是响应还是处理完成,再比较入口与服务 span,随后检查 Redis、消息发布与消费者范围。如果 Redis 区间很短而未覆盖时间很长,就应放弃单纯扩大 Redis 的假设。主题就绪的语义检查可以推广到“实际查询到索引”“实际通过数据库探针读写”等条件。
第 15 章中,旧 trace 返回 200 并未证明 span 全部存在、没有重复或所有故障请求均可查询。可以预先记录期望操作与身份,再逐一检查父子关系、结束状态和完整集合;仍需注意采样策略对可期待集合的影响。
B.5 下一次独立实验
可以选择补充告警恢复、给异步完成定义 SLI、接入日志查询后台或拆成独立 JVM。一次只增加一个主要变量,先写清预期和反例,再修改代码与验收。真实执行后记录提交、环境与原始查询,不要直接沿用本书旧报告为新功能背书。