题目与范围
上下文传播能让跨服务请求保持可理解,但每个下游服务都可能接收并记录这些值。OpenTelemetry 将 Baggage 定义为与追踪上下文相邻的键值数据,并明确提醒传播带来的安全影响。核心能力是分布式边界设计,因此分类为 system-design。
面试官考察点
优秀回答会把追踪上下文与应用元数据分开,为字段定义允许列表和负责人,并阻止敏感值跨越不可信边界。还应覆盖请求头大小、规范编码、采样、重试、异步消息,以及上下文损坏或缺失时的处理。指标要证明传播有价值,避免把它变成失控的数据通道。
先澄清的问题
- 哪些协议承载上下文:HTTP、gRPC、队列还是定时任务?
- 哪些字段用于诊断,哪些会改变行为,各字段由谁负责?
- 租户、区域和第三方服务之间有哪些信任边界?
- 值是否允许进入日志、指标标签,还是只能进入追踪?
- 请求头大小、延迟和可用性预算是多少?
- 上下文损坏时应拒绝、剥离,还是建立新根?
30 秒答题框架
“定义一个小型、带版本的封装,将追踪上下文与批准的业务字段分离。每个边界由策略库校验名称、大小、编码、租户范围和目标信任级别,剥离或拒绝不允许的值,绝不转发密钥。同步和异步边界都要传播,限制请求头,并定义缺失上下文行为。指标记录提取失败、截断、覆盖率、跨租户违规和追踪连接率。”
分步作答
步骤 1:定义上下文契约
建立字段注册表,记录负责人、类型、最大长度、敏感级别、保留期和允许目的地。追踪标识留在追踪协议中,独立载体只放批准的业务元数据。封装带版本,消费者可拒绝未知的关键字段。
步骤 2:执行边界策略
使用共享中间件或 sidecar 解析载体,校验编码和大小,检查租户与信任区,再生成清洗后的载体。不能把任意入站请求头复制到出站请求。第三方和跨租户调用默认视为新的信任根,除非策略明确允许。
步骤 3:处理传输与重试
为 HTTP、gRPC metadata 和消息属性定义对应载体。异步任务只持久化关联所需字段,不能把密钥序列化进队列。重试保留原追踪关系,同时重新校验业务字段,避免重复或过期决策被盲目信任。
步骤 4:设计失败行为
根据端点风险决定剥离或拒绝损坏、超大的上下文;安全时请求本身继续处理并建立新的本地追踪根。暴露带原因码的计数器,不暴露原始值。让策略版本和执行结果可供运维查看。
步骤 5:运营并证明价值
跟踪追踪连接率、提取和注入失败、增加字节数、截断、策略拒绝、跨边界违规和队列序列化错误。避免把高基数原值放进指标标签。为每个协议建立契约测试,在强制拒绝前先灰度策略。
参考答案
“把传播上下文视为不可信数据通道。版本化注册表定义可传播的诊断与业务字段、敏感级别和大小。中间件逐跳校验和清洗,第三方及跨租户调用采用更严格规则;密钥不能进入载体或队列。追踪上下文与业务 Baggage 分开。支持 HTTP、gRPC 和异步属性,定义剥离与拒绝,监控连接率、策略失败、字节数和违规。灰度策略与原因码指标支持逐步收紧而不损失可观测性。”
常见错误
- 转发所有入站请求头 → 不可信数据跨越边界 → 使用允许列表和清洗器。
- 把令牌或 PII 放入 Baggage → 下游日志和服务可能暴露 → 排除敏感数据。
- 用 Baggage 做指标标签 → 基数和成本失控 → 记录有界原因码与维度。
- 忽略队列和重试 → 异步工作丢失或信任过期上下文 → 定义传输契约并重新校验。
- 所有损坏请求都拒绝 → 可观测性与可用性下降 → 按端点风险选择剥离或拒绝。
- 没有大小预算 → 请求头导致代理失败 → 限制字段和总载体大小。
追问
追问 1:租户 ID 应该传播吗?
只有当目的地获准处理该租户,且值已与认证身份核对时才传播。租户 ID 本身不能成为授权依据。
追问 2:追踪上下文与 Baggage 有何区别?
追踪上下文连接 span 和传播状态;Baggage 携带应用自定义键值数据,因此需要更严格的敏感性、所有权和目的地策略。
追问 3:如何阻止请求头增长?
设置字段和总量预算,超限时按原因码拒绝或截断;若必须携带更大内容,改用有界的服务端状态引用。
追问 4:到达不可信边界怎么办?
剥离非批准字段,只继续传播策略允许的追踪信息,并记录策略决定,不记录敏感值。