链路追踪是一种通过分布式系统观察请求流的方法,每个处理步骤都作为独立事件记录时间戳。根据OpenTelemetry 2025年数据,一个trace将请求从入口点到最终响应的完整路径连接起来,经过所有微服务和外部调用。这使开发人员能够在复杂的移动后端架构中发现瓶颈、延迟和故障。
要点
链路追踪是一种分布式观察方法,每个传入请求都会通过系统的所有服务和组件进行跟踪。与显示聚合值(平均响应时间、错误数量)的指标不同,追踪保留了一个特定请求的完整上下文。
每个处理步骤——数据库调用、对另一个微服务的HTTP请求、后台任务的执行——都作为独立单元记录,包含时间戳、状态和属性。根据Google Dapper(2010年原始发布)的数据,追踪能够在分布式系统中定位延迟,精确到单个调用。
追踪对于移动应用尤其重要,因为其后端由数十个微服务组成。用户操作——例如登录账户——可能经过API网关、认证服务、数据库和推送服务。没有trace,几乎无法确定哪个组件拖慢了响应速度。
追踪的基本单元是span。每个span代表一个逻辑操作:HTTP请求、SQL查询、gRPC调用、JSON序列化。Span包含唯一标识符、父标识符、操作名称、开始时间、持续时间、状态和一组属性。
所有属于同一个根请求的span合并成一个trace。根span代表入口点——从移动客户端到API的HTTP请求。子span形成一棵树,每个span通过parent_span_id字段引用其父级。
trace的持续时间等于所有span唯一时间段的总和。如果两个子span并行执行,它们的时间不会相加——这对于正确分析由微服务并行调用引起的延迟至关重要。
每个span可以包含属性——带有元信息的键值对:请求URL、用户ID、API版本、主机名。属性用于过滤和分组trace。除属性外,span还支持事件——带有文本描述的时间戳,例如“缓存未命中”或“重新连接尝试”。
分布式追踪解决了在不同进程和不同机器上创建的span的连接问题。该机制基于上下文传递:当从服务A调用服务B时,会在出站请求中添加一个包含当前trace和父span标识符的标头。
上下文传递的标准协议——W3C Trace Context(traceparent和tracestate标头)和Zipkin B3(X-B3-TraceId、X-B3-SpanId标头)。W3C Trace Context于2021年被W3C联盟采纳为标准,并得到所有主要遥测供应商的支持。
接收请求时,服务B从标头中提取trace_id,并使用该trace_id创建一个子span。这样,请求完成后,来自不同服务的所有span在收集器端合并成一个trace。为此,每个服务必须使用相同的追踪库进行仪表化。
在移动开发中,上下文传递不仅涵盖后端,还包括客户端-服务器交互。移动应用可以在每个API请求的标头中发送trace_id,从而将客户端操作与服务器处理关联起来。适用于iOS和Android的OpenTelemetry SDK支持通过HTTP客户端自动创建和传递trace上下文。
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
class TracingInterceptor : Interceptor {
private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")
override fun intercept(chain: Interceptor.Chain): Response {
val span = tracer.spanBuilder("HTTP POST /api/login")
.setParent(Context.current())
.startSpan()
return chain.proceed(chain.request())
.also { span.end() }
}
}
Kotlin中展示的拦截器为每个对服务器的HTTP请求创建一个span。父上下文通过Context.current()从调用代码传递,这使得客户端侧trace可以与服务器侧trace关联。
OpenTelemetry是收集trace数据的事实标准。它提供了统一的API来生成span,自动检测流行库,以及灵活的机制将数据导出到不同的后端:Jaeger、Zipkin、Grafana Tempo、Datadog、New Relic。
OpenTelemetry支持自动为流行框架创建span:Spring Boot、Ktor、Flask、Express、gRPC。开发人员只需向项目添加依赖,库就会自动拦截传入和传出的请求。Java的自动检测使用javaagent,它在不修改源代码的情况下动态修改字节码。
针对移动平台,OpenTelemetry提供了Swift SDK和Kotlin SDK。它们自动为网络请求(URLSession、OkHttp)、数据库操作(CoreData、Room)和后台任务创建span。开发人员可以为业务逻辑添加自定义span。
收集到的span通过OTLP(OpenTelemetry协议)发送到收集器。收集器可以缓冲、过滤和将数据导向一个或多个存储系统。根据OpenTelemetry文档,使用gRPC导出时,从生成span到其在仪表板上显示的典型延迟为2至5秒。
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation
let instrumentation = URLSessionInstrumentation()
instrumentation.enable()
let tracer = OpenTelemetry.instance.tracerFactory
.get("mobile-monitoring")
let span = tracer.spanBuilder("fetch-user-profile")
.setAttribute(key: "user.id", value: userId)
.startSpan()
span.end()
Swift中的代码激活网络层的自动检测,并为获取用户配置文件的操作创建自定义span。user.id属性允许随后按特定用户过滤trace。
在高负载系统中,不可能追踪每个请求——这会给存储和网络带来不可接受的负载。采样通过仅保存部分trace来解决此问题。策略的选择直接影响到数据的完整性和基础设施成本。
关于是否保存trace的决定在其创建时刻做出——在根span中。最简单且最常用的方法:固定百分比的请求(例如5%)被保存,其余的丢弃。缺点——不能保证罕见的错误会被捕获。OpenTelemetry中的概率采样器支持设置0.0到1.0之间的概率。
决定推迟到trace的所有span完成之后。分析器评估trace是否包含错误、超时或有趣的属性,然后才保存它。这种方法需要在收集器中缓冲所有span,这增加了内存消耗。根据Grafana Labs的数据,在罕见但关键错误的系统中,尾部采样在“有用数据价格”比率方面效率高出40-60%。
| 策略 | 优点 | 缺点 |
|---|---|---|
| Fixed probability | 简单,可预测的负载 | 遗漏罕见事件 |
| Rate limiting | 数据量有保障 | 覆盖不均匀 |
| Tail-based | 捕获所有错误 | 高内存消耗 |
| Adaptive | 成本与覆盖的平衡 | 配置复杂 |
日志记录记录独立事件及其重要性级别(info、warn、error),但不会将它们关联到单个请求的上下文中。相反,追踪创建了一个属于端到端请求的结构化操作树。在实践中,这两种方法并不相互排斥,而是相互补充。
日志对于特定错误的详细分析非常有效:开发人员可以看到确切的消息、堆栈跟踪和变量值。追踪回答了“为什么请求需要5秒”的问题——它显示哪个微服务或调用占用了最多的时间。根据Honeycomb(2024年)的数据,将追踪与日志记录结合使用的团队发现事件根本原因的速度提高了2.3倍。
现代方法——可观测性——将trace、指标和日志整合到一个统一系统中。OpenTelemetry支持这三个信号之间的关联:每个span可以包含指向相关日志的引用,指标可以用trace_id标记以导航到特定的trace。
常见问题
监控显示系统的聚合指标——平均响应时间、每分钟错误数、CPU负载。追踪显示一个特定请求经过所有组件的路径。监控回答“发生了什么”,追踪回答“为什么发生”。
对于生产系统,头部采样时1-5%的请求就足够了。如果系统很少产生错误,建议使用尾部采样,专注于捕获所有错误的trace。对于staging环境,允许无限制地追踪100%的请求。
主要工具:Jaeger(Uber的解决方案,开源)、Grafana Tempo(可扩展的trace存储)、Datadog APM、New Relic Distributed Tracing、AWS X-Ray和Honeycomb。它们都支持OpenTelemetry标准进行数据接收。
可以,本地追踪在单个进程内工作。适用于iOS和Android的OpenTelemetry SDK为本地操作创建span:从数据库读取、图像处理、网络请求。这类trace不是分布式的,但对于诊断客户端性能非常有用。
现代追踪库在头部采样时增加不到1%的开销。OpenTelemetry使用异步数据导出,不会阻塞主线程。对于移动设备,建议限制创建span的频率并使用自适应采样策略。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。