日志系统与链路追踪

共 20 题
📑 题目列表 20 题
#
★★★

1. Fluent Bit 与 Fluentd 的差异是什么,Fluent Bit 在 Kubernetes 日志采集中如何部署?

请说明 Fluent Bit 与 Fluentd 的差异,以及 Fluent Bit 在 Kubernetes 日志采集中如何部署?

  • Fluent Bit 与 Fluentd 的差异
  • Fluent Bit 的架构与特性
  • 在 K8s 中的部署方式

Fluentd 与 Fluent Bit 都是 CNCF 的日志采集器,但定位不同:Fluentd 功能全面、插件生态丰富(input/filter/output 插件多),但资源占用高、性能相对较低;Fluent Bit 是轻量级、高性能的采集器,用 C 编写、内存占用低(约数百 KB~数 MB)、吞吐高,擅长采集与转发,但插件与处理能力弱于 Fluentd。通常两者配合:Fluent Bit 作为轻量采集端(DaemonSet)在节点采集日志,可转发到 Fluentd 聚合做复杂处理,再输出到后端。在 K8s 中,Fluent Bit 通常以 DaemonSet 部署,每个节点一个实例,采集容器标准输出(/var/log/containers)与文件日志,通过 kubernetes filter 解析容器/命名空间/Pod 标签元数据,再经 output 输出到 Elasticsearch、Loki、Kafka 等。部署时配置 tail 插件监听日志文件、解析器(parser)按格式解析、filter 添加元数据、output 路由。

差异的本质是"轻量高性能 vs 功能全面":Fluent Bit 适合资源受限的采集端,Fluentd 适合功能强大的聚合处理。K8s 部署用 DaemonSet 就近采集,配合元数据注入是常态。

#
★★★

2. Fluentd 日志采集的完整流程中 input、parser、filter、output 插件如何串联实现采集与转发?

请说明 Fluentd 日志采集的完整流程,即 input、parser、filter、output 插件如何串联实现采集与转发?

  • Fluentd 的插件体系
  • input/parser/filter/output 的串联
  • 数据流与标签路由

Fluentd 通过插件串联实现采集与转发,核心流程为 input → parser → filter → output。input 插件定义数据来源(如 tail 监听文件、forward 接收、http、syslog),捕获事件后 parser 插件把原始数据解析为结构化记录(按格式如 json、regexp、apache 解析字段);filter 插件对事件做处理(添加/删除字段、grep 过滤、record 变换、geoip 等);output 插件把处理后的数据输出到目标(如 elasticsearch、file、s3、kafka、rewrite_tag)。事件携带 tag(标识来源/类型),通过 <match> 规则按 tag 路由到不同 output,实现分流。标签与路由是串联的关键:配置中定义 <source><filter><match> 块,事件从 input 进入,经 filter 处理,再按 tag 匹配到 output。整个流程在内存中按事件流处理,支持缓冲(buffer)与重试(retry),保证可靠转发。

Fluentd 的核心是"事件流 + 标签路由":input 采集、parser 解析、filter 处理、output 输出,按 tag 路由。理解插件串联与标签路由是掌握 Fluentd 配置的关键。

#
★★

3. OpenTelemetry 中 TracerProvider 的作用,即如何创建 tracer 并管理采样与导出配置?

请说明 OpenTelemetry 中 TracerProvider 的作用,以及如何创建 tracer 并管理采样与导出配置?

  • TracerProvider 的作用
  • tracer 的创建
  • 采样与导出配置

TracerProvider 是 OpenTelemetry 中创建与管理 tracer 的入口,是追踪的"工厂"。它持有全局配置:采样器(Sampler)决定哪些 span 被采样、资源(Resource)属性(如 service.name)、span processor 与导出器(Exporter)链。应用通过 TracerProvider 获取 Tracer,再创建 span 来记录追踪数据。创建 tracer:tracerProvider.getTracer("service-name", "version") 得到带名称与版本的 tracer,用于创建 span。采样与导出配置:TracerProvider 配置 Sampler(如 parentbased_always_on、traceidratio、tail-based 由 collector 决定)控制采样率;配置 SpanProcessor(batch 异步导出)与 Exporter(OTLP、Jaeger、Console)控制数据导出。TracerProvider 可全局单例(GlobalTracerProvider)或按服务实例化,支持多 provider 与上下文传播。SDK 的 TracerProvider 实现把这些配置集中管理,是追踪的"配置中枢"。

TracerProvider 是"追踪的工厂与配置中枢":集中管理采样、导出、资源与 span 处理,应用通过它获取 tracer 并创建 span。理解采样与导出配置在 TracerProvider 上集中声明是关键。

#
★★

4. span 的关键语义中 span kind、status 与 attributes 如何影响链路分析与告警

请说明 span 的关键语义,即 span kind、status 与 attributes 如何影响链路分析与告警?

  • span kind 的语义
  • span status 的语义
  • attributes 对分析与告警的作用

span 的关键语义包括 kind、status、attributes。span kind 描述 span 的角色:CLIENT(客户端调用)、SERVER(服务端处理)、PRODUCER(生产者发消息)、CONSUMER(消费者收消息)、INTERNAL(内部操作),kind 影响链路如何连接与展示(如 SERVER 与 CLIENT 配对形成跨服务调用)。span status 描述操作结果:UNSET/OK/ERROR,status=ERROR 表示失败,是告警与错误分析的基础(按错误 span 统计错误率)。attributes 是键值对的附加信息(如 http 状态码、db 语句、错误信息),用于:细分分析(按 service、路由、环境维度聚合)、告警标签(按错误类型、错误码分组)、上下文(记录关键参数)。三者影响链路分析:kind 决定链路结构,status 决定是否计为错误,attributes 提供分析维度与告警标签。实践上,错误 span 需设 status=ERROR 并记录 error attributes,告警按 status 统计、按 attributes 细分。

三个语义各有分工:kind 定义角色/结构,status 定义成败,attributes 提供可分析的维度。链路分析与告警都依赖它们:status 决定错误,attributes 决定如何分组与告警。

#
★★

5. trace_id、span_id、parent_id 如何通过上下文传播跨服务串联成完整调用链?

请说明 trace_id、span_id、parent_id 如何通过上下文传播跨服务串联成完整调用链?

  • 三个 ID 的作用
  • 上下文传播机制
  • 跨服务串联

trace_id 标识一条完整的调用链(全局唯一),span_id 标识单个 span,parent_id(parent_span_id)标识当前 span 的父 span。三者关系:同一 trace_id 下,每个 span 有唯一 span_id 与 parent_id,形成树状结构。跨服务串联的关键是"上下文传播":客户端发起请求时,把 trace_id、当前 span_id 等上下文注入请求头(如 W3C tracecontext 的 traceparenttracestate),服务端接收后从请求头提取上下文,创建新 span 并以其"父 span_id"等于请求头中的 span_id,从而把服务端的 span 挂到调用链上。如此沿调用链传播,各服务 share 同一 trace_id,通过 parent_id 串成完整的调用链。传播机制包括 HTTP 头、gRPC 元数据、消息队列消息头等,OpenTelemetry 用 Context Propagation 抽象统一处理。跨语言、跨服务一致使用标准上下文头是串联成功的前提。

串联的核心是"上下文传播 + ID 关联":trace_id 保证同一链路,parent_id 建立父子关系,上下文传播把信息带过服务边界。标准化传播(W3C tracecontext)是跨语言串联的关键。

#
★★

6. 如何配置 OpenTelemetry 将 Trace 数据通过 Jaeger exporter 导出到 Jaeger?

请说明如何配置 OpenTelemetry 将 Trace 数据通过 Jaeger exporter 导出到 Jaeger?

  • Jaeger exporter 的配置
  • 导出协议与端点
  • 与 SDK/Collector 集成

将 Trace 数据通过 Jaeger exporter 导出到 Jaeger,可在 SDK 或 Collector 侧配置。SDK 侧:在应用初始化时配置 Jaeger exporter,指定 Jaeger 的端点(如 jaeger:14250 的 gRPC,或 jaeger:14268 的 HTTP/thrift),并配置 BatchSpanProcessor 异步导出。Collector 侧:在 pipeline 的 exporters 中配置 jaeger,指定 Jaeger 端点与协议(gRPC/HTTP),把 traces 从 OTLP receiver 处理后导出到 Jaeger。示例(Collector):exporters: { jaeger: { endpoint: jaeger:14250, tls: {} } },pipeline 中 traces 的 exporters 引用 jaeger。也可用 OTLP exporter 导出到 Jaeger 的 OTLP 端点(新版本 Jaeger 支持 OTLP)。常见做法:应用用 OTLP 发送到 Collector,Collector 用 Jaeger exporter 转发到 Jaeger,或直接集成 Jaeger 的 OTLP 接收。配置要点是端点、协议匹配与采样/批量设置。

导出到 Jaeger 的核心是"配置 exporter 端点与协议":SDK 或 Collector 侧的 jaeger exporter 指定 Jaeger 地址。现代趋势是统一用 OTLP,Jaeger 新版本也支持 OTLP 直连。

# Collector 用 Jaeger exporter 导出到 Jaeger
# exporters:
#   jaeger:
#     endpoint: jaeger:14250
#     tls: { insecure: true }
# service:
#   pipelines:
#     traces:
#       exporters: [jaeger]
#
★★

7. 日志与追踪的联合排障中如何用 traceId 串联?

请说明日志与追踪的联合排障,即如何用 traceId 串联日志与调用链?

  • traceId 注入日志
  • 日志与追踪关联
  • 联合排障流程

用 traceId 串联日志与追踪的方法:在日志库中注入当前 trace_id(与 span_id),使每条日志携带 traceId,从而在日志系统与追踪系统间建立关联。实现上,日志库(如 slf4j 的 MDC、logrus 的 field)从 OpenTelemetry 上下文提取 trace_id 并加入日志字段,跨语言统一格式。排障流程:追踪系统发现某条慢/错误 trace → 用其 traceId 在日志系统检索该请求的全部日志 → 结合日志细节与 span 数据定位根因;或从日志中某个 traceId 跳到追踪系统看完整调用链。联合价值:追踪给出"请求走了哪些服务、每段耗时",日志给出"每个服务内部发生了什么(异常堆栈、参数、业务反馈)",两者互补。打通的关键是 traceId 在日志与追踪中一致,且日志系统支持按 traceId 索引。实践中用 traceId 做"join key",实现日志↔追踪双向跳转。

联合排障的核心是"traceId 作为关联键":追踪定位链路,日志补充细节,用同一 traceId 双向跳转。核心是日志注入 traceId 并支持按它检索。

#
★★

8. 日志保留与归档策略中不同级别/业务日志的保留周期、冷热分层与成本控制以及合规留存(审计日志)与容量规划如何平衡?

请说明日志保留与归档策略,包括不同级别/业务日志的保留周期、冷热分层与成本控制,以及合规留存与容量规划的平衡?

  • 不同日志的保留周期
  • 冷热分层与归档
  • 合规留存与容量平衡

日志保留策略按"级别、业务、合规"差异设置:debug/info 日志短期保留(如数天至数周),error/warn 日志中期保留(如数月),审计日志与合规日志长期保留(如半年至数年,按等保/监管要求)。冷热分层:热日志(近期、高频查询)存高性能存储(如 ES 热节点),冷日志(历史、低频查询)转存低成本存储(对象存储、ES 冷节点、归档),配合降采样与压缩。成本控制:按级别/来源过滤低价值日志、日志采样、压缩、归档时降精度。合规留存与容量规划平衡:合规日志必须长期、不可篡改保留,但容量有限,需把合规日志与业务日志分离、单独存储与归档,用压缩与归档降成本,同时满足保留周期;容量规划需基于日志产生速率、保留周期预估存储,并设置配额与告警。核心是"按价值分级保留 + 热冷分层 + 合规隔离"。

保留策略的核心是"按价值与合规分级":低价值短期、高价值与合规长期,热冷分层降成本。合规留存与容量规划的平衡靠"业务日志与合规日志分离、归档压缩"。

#
★★

9. 基于日志的告警与稳定性中日志中错误率、异常模式如何转化为告警规则以及与指标告警相比的误报与延迟特征?

请说明基于日志的告警与稳定性,日志中错误率、异常模式如何转化为告警规则,以及与指标告警相比的误报与延迟特征?

  • 日志告警规则的设计
  • 错误率与异常模式
  • 与指标告警的对比

基于日志的告警是把日志中的错误率、异常模式转化为告警规则。落地方式:对日志做解析并统计错误率(如按 service 统计 error 级日志占比),设定阈值(如错误率 > 5% 持续 5 分钟);或用模式匹配检测异常(如特定异常堆栈、特定错误码出现频率突增、连续失败)。实现上常用指标化日志(Loki 的 logql 计算错误率、ELK 的聚合告警)或日志分析引擎统计。与指标告警相比:误报与延迟特征——日志告警依赖日志内容,能捕获"业务语义错误"(指标看不到的异常),但日志可能不全、格式不统一导致误报;延迟上,日志采集、解析、聚合链路慢,告警延迟通常高于指标(秒级到分钟级);指标告警基于聚合指标,延迟低、稳定,但只能反映"可数值化的状态",无法捕捉日志反映的业务异常。实践上两者结合:指标告警抓整体状态,日志告警抓业务异常,并设置合理的解析与聚合窗口控制误报。

日志告警的价值是"捕捉业务语义异常",代价是延迟与误报(依赖日志质量)。与指标告警互补:指标实时稳定、日志语义丰富,按场景组合。

#
★★

10. 日志、指标与追踪的关联分析中事件时间对齐、traceId 注入日志与 metric 标签如何打通三信号以及排障时的典型工作流?

请说明日志、指标与追踪的关联分析,包括事件时间对齐、traceId 注入日志与 metric 标签如何打通三信号,以及排障时的典型工作流?

  • 三信号的关联方式
  • 时间对齐与 traceId 注入
  • 典型排障工作流

打通日志、指标、追踪三信号,靠"时间对齐 + 共同的关联键"。时间对齐:指标、日志、追踪都带时间戳,按时间窗口对齐,识别"同一时间段内发生了什么"。关联键:traceId 注入日志(日志带 trace_id/span_id),追踪与日志用 traceId 关联;metric 标签(如 service、HTTP 状态码、错误类型)与日志/追踪的语义对齐,用 service 维度聚合。排障典型工作流:一、指标告警(如错误率上升、延迟升高)→ 缩窄时间范围;二、用指标标签(service、端点)定位到服务;三、跳转到该时间段的追踪,看慢/错误 trace 的调用链;四、用 traceId 检索该请求的日志,看异常堆栈与业务细节;五、结合日志与 span 数据定位根因。打通的关键是统一时间基准、traceId 贯穿日志、指标标签与日志/追踪语义一致,并借助可观测性平台的一体化跳转能力。

三信号关联的核心是"统一时间 + 统一 key(traceId、service)":指标抓范围、追踪看链路、日志看细节,按时间对齐与 traceId 串联形成完整排障闭环。

#
★★

11. 日志系统的容量与降级中采集端背压、队列溢出与存储满时的行为设计以及日志丢失与业务影响如何权衡?

请说明日志系统的容量与降级设计,包括采集端背压、队列溢出与存储满时的行为,以及日志丢失与业务影响的权衡?

  • 采集端背压与队列溢出
  • 存储满的行为设计
  • 日志丢失与业务影响权衡

日志系统容量与降级设计需处理背压、队列溢出与存储满。采集端背压:当下游处理慢时,采集端(如 Fluent Bit、Fluentd)应支持背压(backpressure),限制内存/队列占用,避免采集端 OOM;队列溢出:当队列满时,行为策略可选——丢弃新日志(优先保业务)、阻塞(可能影响业务)、写磁盘缓冲(可靠但占磁盘)。存储满时的行为:日志存储(如 ES、Loki)满时,系统应拒绝新写入或触发滚动/归档,而非无限堆积导致存储故障。日志丢失与业务影响权衡:日志采集是"尽力而为",可以适度丢日志(采样、溢出丢弃)但不能影响业务进程;因此设计上采集端有内存上限、背压保护、写盘缓冲,日志丢失时记录丢弃统计并告警,优先保证业务可用性。核心原则是"日志系统是辅助系统,不能拖垮业务",通过降级(丢日志、限流)保证业务优先。

日志系统降级的核心原则是"业务优先":日志可丢、业务不能挂。通过背压、队列上限、溢出策略与存储满保护,在容量不足时平滑降级,并记录丢弃以告警。

#

12. 可观测数据成本控制中日志采样、追踪采样与指标降精度的组合策略如何设计

请说明可观测数据成本控制,即日志采样、追踪采样与指标降精度的组合策略如何设计?

  • 日志采样策略
  • 追踪采样策略
  • 指标降精度与组合

可观测数据成本控制需按信号类型设计组合策略。日志采样:对高吞吐日志按级别/规则采样(保留 error、过滤 debug、按比例采样 info),采集端 tail 采样或按规则过滤。追踪采样:头部采样(按 trace_id 比例随机采样)或尾部采样(保留完整链路、丢弃低价值),常用 tail-based 保留异常链。指标降精度:降低采集频率、对低价值指标降采样、用 recording rules 聚合(聚合到分钟/小时)、downsampling 历史数据、控制标签基数。组合策略设计:按"价值分级"——高价值(错误、慢请求、关键业务)全量,低价值(常规 info、debug、正常请求)采样降精度;按信号间关联——日志与追踪共享采样(如都保留异常,采样正常以保留 traceId 关联);按存储分层——热数据高精度短期、冷数据降精度长期。策略目标是"用最小成本保留排障价值":优先保证错误与关键链路完整,常规数据按需降量。

组合策略的核心是"按价值分级 + 信号间协同":错误/关键全量,常规采样降精度,日志与追踪共享采样保留关联。核心是"成本与排障价值匹配"。

#

13. 基于追踪的延迟分解中如何在 span 树上定位跨服务瓶颈与外部依赖耗时

请说明基于追踪的延迟分解,即如何在 span 树上定位跨服务瓶颈与外部依赖耗时?

  • span 树与延迟分解
  • 跨服务瓶颈定位
  • 外部依赖耗时

基于追踪的延迟分解,是在 span 树上逐层分析耗时,定位瓶颈。span 树反映调用层级,每个 span 的 duration 表示该段耗时,分析时逐层对比:比较某 span 总耗时与其子 span 总耗时之和,差值即"自身处理耗时"(self time),可发现某服务自身处理慢还是等待下游。跨服务瓶颈定位:沿 span 树找出耗时最大的子 span,逐层下钻到瓶颈服务;用"自顶向下"看总耗时贡献,"自底向上"找具体热点。外部依赖耗时:识别依赖外部(DB、HTTP、MQ、Redis)的 span,统计其耗时与占比,判断瓶颈是否在外部依赖(如 DB 查询慢、外部 API 慢)。工具上,span 瀑布图(waterfall)直观展示每段耗时,配合按 service/operation 聚合的耗时统计可定位高频慢点。延迟分解的产出是"谁最慢、慢在哪、是自身还是外部依赖"。

延迟分解的核心是"span 树上的耗时差分":用 span 总耗时减子 span 总和得 self time,定位自身瓶颈;逐层下钻定位跨服务瓶颈;识别外部依赖 span 判断是否外部慢。

#

14. 日志与追踪关联的工程实现中日志库如何自动注入 trace_id/span_id 以及跨语言如何保持格式一致

请说明日志与追踪关联的工程实现,即日志库如何自动注入 trace_id/span_id,以及跨语言如何保持格式一致?

  • 日志库注入 trace_id/span_id
  • 自动注入机制
  • 跨语言格式一致

日志库自动注入 trace_id/span_id 的机制:日志库与 OpenTelemetry 集成,记录日志时从当前上下文(Context)提取 trace_id 与 span_id,作为日志字段自动附加。实现上,Java 用 MDC 由 OpenTelemetry 的 Logback/Log4j appender 自动填充,Go 用 logrus/zap 的 hook 从 context 提取,Python 用 logging 的 concurrency 扩展或 filter。自动注入依赖上下文传播:请求进入时设置 trace 上下文,日志库在日志事件中读取。跨语言格式一致:约定字段名(如 trace_idspan_id)与格式(如 32 位 hex trace_id、16 位 hex span_id),并统一采集端(如 Fluent Bit 解析所有语言日志的同一字段)。实现方式:各语言日志库使用同一字段名与 W3C tracecontext 的 ID 格式,采集端统一解析,保证跨语言日志可互相关联。这是"日志↔追踪联动"的工程基础。

工程实现的核心是"日志库从上下文提取 trace 信息 + 统一字段名与格式"。跨语言一致靠"约定字段名 + 标准 ID 格式 + 统一采集解析"。

#

15. 追踪可视化的应用中服务依赖图、span 瀑布图与火焰图在性能分析中的使用场景

请说明追踪可视化的应用,即服务依赖图、span 瀑布图与火焰图在性能分析中的使用场景?

  • 服务依赖图
  • span 瀑布图
  • 火焰图

追踪可视化有服务依赖图、span 瀑布图与火焰图三类,用于不同场景。服务依赖图:展示服务间的调用关系(谁调用谁、频率、延迟、错误),用于整体架构认知、识别依赖异常(如某服务依赖过多、环状依赖、单点依赖)、排查"某个服务故障影响哪些下游"。span 瀑布图:展示单条 trace 的 span 时间轴(每层 span 的耗时与重叠),用于单请求延迟分析,直观看到"慢在哪一段、哪段等待外部"。火焰图:把 span 按调用栈聚合,展示耗时占比(x 轴时间、y 轴调用深度),用于聚合分析——高频慢操作、热点函数/span 聚类,适合"整体性能画像"。使用场景:依赖图看全局拓扑,瀑布图看单请求明细,火焰图看聚合热点。三者互补:依赖图定位受影响范围,瀑布图下钻单请求,火焰图聚合找共性热点。

三类可视化分工明确:依赖图看全局拓扑、瀑布图看单请求明细、火焰图看聚合热点。性能分析按"全局→单请求→聚合"的顺序组合使用。

#

16. 追踪后端选型中 Jaeger、Tempo 与 Zipkin 在存储、采样与多租户上的差异及成本评估

请说明追踪后端选型,即 Jaeger、Tempo 与 Zipkin 在存储、采样与多租户上的差异及成本评估?

  • 各后端存储架构
  • 采样与多租户差异
  • 成本评估

Jaeger、Tempo、Zipkin 是常见追踪后端。存储:Jaeger 支持多种存储(Elasticsearch、Cassandra、Badger、内存),基于 span 索引,可扩展但存储运维较重;Tempo 基于对象存储(S3/GCS/MinIO),以 trace 为块存储 + 索引,存储成本低、架构简单,适合与 Grafana 生态集成;Zipkin 支持 Cassandra/Elasticsearch/内存,历史较久、轻量。采样:三者都支持采样(Jaeger 有 head/remote sampling,Tempo 支持自适应/尾部采样,Zipkin 支持头采样),但采样能力与复杂度不同。多租户:Jaeger 与 Zipkin 多租户能力弱(需自行隔离),Tempo 支持多租户(按 tenant 隔离命名空间)。成本评估:Tempo 对象存储成本低、适合大规模;Jaeger 依赖 ES/Cassandra 存储成本与运维成本较高;Zipkin 轻量但扩展有限。选型权衡:与 Grafana 深度集成选 Tempo、需要强存储自定义选 Jaeger、轻量简单选 Zipkin,考虑存储成本、多租户与运维复杂度。

选型核心是"存储成本 + 多租户 + 生态集成":Tempo 对象存储低成本、多租户、Grafana 生态好;Jaeger 功能强但存储运维重;Zipkin 轻量简单。成本评估需考虑存储与运维。

#

17. 追踪埋点的落地中自动插桩(auto-instrumentation)与手动埋点的分工、中间件(HTTP/DB/MQ)的集成方式

请说明追踪埋点的落地,即自动插桩(auto-instrumentation)与手动埋点的分工,以及中间件(HTTP/DB/MQ)的集成方式?

  • 自动插桩与手动埋点
  • 中间件集成
  • 分工与权衡

追踪埋点分为自动插桩与手动埋点。自动插桩(auto-instrumentation):通过字节码增强(Java Agent)、钩子(Python、Go)自动拦截常见库(HTTP、DB、MQ、框架),无需改代码即可生成 span,适合快速覆盖、降低侵入;手动埋点:在业务关键路径显式创建 span 并添加 attributes,用于表达业务语义(自定义操作、关键步骤),适合业务专属逻辑。分工:自动插桩覆盖"通用框架层"(HTTP 请求、DB 查询、MQ 收发),手动埋点覆盖"业务自定义层"(业务步骤、自研逻辑)。中间件集成方式:HTTP 用自动插桩拦截客户端/服务端;DB 用钩子拦截 SQL 并记录语句、耗时;MQ 用生产/消费插桩生成 PRODUCER/CONSUMER span 并传播上下文。落地策略:先用自动插桩快速覆盖,再对关键业务补手动埋点,兼顾"覆盖率"与"业务语义"。

分工是"自动覆盖通用、手动覆盖业务":自动插桩低侵入快速覆盖框架层,手动埋点补充业务语义。中间件集成靠生态插桩,落地时先自动后手动。

#

18. 追踪数据的隐私与脱敏中 URL、查询参数与请求体的敏感字段如何在采集与存储阶段脱敏

请说明追踪数据的隐私与脱敏,即 URL、查询参数与请求体的敏感字段如何在采集与存储阶段脱敏?

  • 敏感字段识别
  • 采集阶段的脱敏
  • 存储阶段的保护

追踪数据可能包含隐私(URL、查询参数、请求体的 token、密码、身份证等),需在采集与存储阶段脱敏。采集阶段:在 SDK 埋点或 Collector 层对敏感字段处理——用 span processor/transform 规则删除或替换敏感 attribute(如清空 http.url 的查询参数、把 http.request.body 脱敏为 ***),或配置插桩只采集必要字段、不采集 body。采集端用 OTTL/processor 对 attributes 做 replace/delete。存储阶段:对存储的 trace 数据做加密(静态加密)、设置访问控制(只有授权角色可查原始数据)、审计日志记录访问;对跨环境/日志导出时脱敏。实现上,脱敏策略包括"黑名单字段删除、白名单字段保留、正则替换敏感值",并尽量在源头(SDK/采集端)脱敏,避免敏感数据进入存储。核心是"默认不采集敏感数据 + 必要字段在采集端脱敏 + 存储端加密与访问控制"。

脱敏的核心是"源头少采 + 采集端替换 + 存储端保护":在 SDK/Collector 对敏感 attributes 脱敏,存储端加密与权限控制,避免隐私进入存储。默认不采集是最好策略。

#

19. 追踪采样策略中全量采集的成本与头部/尾部采样的失真如何按服务重要性混合采样

请说明追踪采样策略,包括全量采集的成本 vs 头部/尾部采样的失真,以及如何按服务重要性混合采样?

  • 全量采集的成本
  • 头部/尾部采样的失真
  • 按重要性混合采样

追踪采样需权衡成本与失真。全量采集:保留所有 trace,信息最全,但存储与带宽成本高,高 QPS 下不可承受。头部采样(head-based):在请求开始随机按比例采样(如 trace_id 哈希),成本低、实现简单,但会丢失异常/慢请求(未被采样),且无法按完整 trace 信息决策,存在"采样失真"(关键请求可能被丢)。尾部采样(tail-based):采集后按 trace 完整信息决定保留,能精确保留异常链,但成本与延迟较高。混合采样:按服务重要性分层——核心服务(支付、登录)全量或高采样,非核心服务低采样;按请求重要性(错误、慢请求、关键业务全量,正常请求低采样);结合头部采样(过滤低价值)+ 尾部采样(保留异常)。目标是把采集成本投向"有排障价值"的 trace,同时控制失真。实践上设定分服务采样率,用 tail-based 保留错误链,用 head-based 控制规模。

采样决策的核心是"成本与失真的平衡":全量贵、头部易失真、尾部准但贵。按服务与请求重要性混合采样,把成本投向高价值 trace,是工程常态。

#

20. 集中日志系统的架构分层中采集端、缓冲队列、处理管道与存储查询如何扩展与降级

请说明集中日志系统的架构分层,即采集端、缓冲队列、处理管道与存储查询如何扩展与降级?

  • 日志系统的分层架构
  • 各层扩展方式
  • 降级策略

集中日志系统分四层:采集端(agent,如 Fluent Bit/Fluentd、Filebeat)、缓冲队列(Kafka 等)、处理管道(logstash/fluentd 的聚合、解析、索引)、存储查询(ES/Loki/ClickHouse)。扩展:采集端按节点/实例水平扩展(DaemonSet 随节点);缓冲队列用 Kafka 水平扩展分区、按 QPS 扩容,解耦采集与处理;处理管道按消费者组水平扩展,处理能力随分区数扩容;存储查询用 ES 分片/冷热节点、Loki 分片/对象存储、ClickHouse 分片扩展,查询按多副本/分片扩展。降级:采集端背压与队列上限(吞吐不足时丢日志保业务);缓冲队列满时采集端阻塞或降级;处理管道慢时通过队列缓冲、限流;存储满时滚动/归档、拒绝新写入或降精度。架构价值:分层解耦(采集/处理/存储独立扩展),缓冲队列吸收峰值、隔离故障(存储故障不影响采集)。降级原则是"业务优先、逐层降级、记录丢弃"。

分层架构的价值是"解耦 + 独立扩展 + 缓冲隔离":缓冲队列吸收峰值、隔离故障,各层按需水平扩展。降级核心是"业务优先、逐层降级、记录丢弃并告警"。