13 链路追踪你们是怎么做的

vvEcho 2026-03-18 09:59:40
Categories: Tags:

分布式链路追踪本质是通过TraceId和SpanId把一次请求在多个服务之间串起来,形成完整调用链。
我们一般通过自动埋点结合关键业务手动埋点来实现,比如RPC调用自动生成Span,核心交易链路会手动增强。
在实现上重点是上下文传递,比如通过HTTP Header或者RPC隐式传参来传递TraceId,同时针对线程池和异步场景做了上下文透传。
数据会通过OpenTelemetry上报到Jaeger进行存储和展示,同时通过采样机制控制性能开销。

对于可观测性,我理解它不只是监控,而是通过Metrics、Logs和Trace三者结合,让系统内部状态对我们是“可见的”。
Metrics用于发现问题,Trace用于分析链路,Logs用于定位细节,在高并发交易系统中,这三者配合可以快速定位问题根因

一般我们用SkeyWalking实现链路追踪,SkyWalking的分布式链路追踪原理是:
我们在部署服务的时候会在启动命令中加上对应的agent包,或者在kubernetes中通过环境变量的方式添加SkyWalking的配置 这样所有的pod启动时都会自动添加SkyWalking的agent包,然后SkyWalking会提供字节码增强技术来对代码进行插桩,插桩的目的是把调用关系写入到SkyWalking的存储中,这样SkyWalking就可以通过调用关系找到调用链。

1.入口处生成traceId
2.自动埋点,每个服务的agent都会拦截http rpc 数据库链接请求 自动生成对应的操作的spanId
3.将traceId和spanId写入到http header中,传递给下一个服务
4.在下个节点时,传过来的spanId作为父spanId,生成新的spanId,并写入到http header中
5.每个agent都会将数据异步上报到OAP(skywalking的数据分析层)
6.OAP会根据traceId将spanId进行聚合,生成调用链;然后在满足一定的条件后会批量下到数据库,例如一分钟统计一次,10s刷新一次;或者内存队列满了写一次,一般会写到es里

存到es里需要提前建索引吗?

不需要,OAP会根据你选择存储的配置自动建立对应的索引,例如配置的是es就会建立对应的es相关的索引

skywalking的索引用的是啥数据类型,为啥不用text?

SkyWalking 在 Elasticsearch 中的 mapping 设计是以聚合分析为核心的。
大部分字段,比如服务名、接口名、traceId 等,都会使用 keyword 类型,而耗时、状态码等则使用数值类型。

之所以不用 text,是因为 text 会进行分词,主要用于全文检索,但 SkyWalking 的核心需求是精确匹配和指标聚合,比如统计 QPS、延迟分布等。

同时 text 类型在聚合场景下性能较差,还会增加存储和计算开销,因此整体设计上会尽量避免使用 text,而优先选择 keyword 和数值类型