游乐游手机版
首页/科技数码/文章详情

在多语言的分布式系统中如何传递 Trace 信息

时间:2025-12-15 20:15
在解决这个问题之前想要搞清楚 Trace 是如何跨语言以及跨应用传递的。其实也可以类比为在分布式系统中如何传递上下文;既然要传递数据那就涉及到系统之间的调用,也就是我们常说的 RPC(remote

在解决这个问题之前想要搞清楚 Trace 是如何跨语言以及跨应用传递的。其实也可以类比为在分布式系统中如何传递上下文;既然要传递数据那就涉及到系统之间的调用,也就是我们常说的 RPC(remote procedure call)。

背景

图片图片

图片图片

图片图片

前段时间有朋友问我关于spring cloud的应用在调用到 Go 的 API 之后出现 Trace 没有串联起来的问题。

完整的调用流程如下:

┌──────┐ │Client│ └┬─────┘ ┌▽──────────────────┐│SpringCloud GateWay│└┬──────────────────┘┌▽──────────────┐ │SpringBoot(app)│ └┬──────────────┘ ┌▽──────────┐ │Feign(http)│ └┬──────────┘ ┌▽─────┐ │Go Gin│ └──────┘

根因

在解决这个问题之前想要搞清楚 Trace 是如何跨语言以及跨应用传递的。

其实也可以类比为在分布式系统中如何传递上下文;既然要传递数据那就涉及到系统之间的调用,也就是我们常说的RPC(remote procedure call)。

提到 PRC 我们常见的一般有两种协议:

• 基于 HTTP 协议,简单易读,兼容性好

• 基于 TCP 的私有协议,高效性能更佳

基于 TCP 私有协议的又诞生出许多流行的框架,比如:

• Dubbo

• Thrift

• gRPC(基于 HTTP2,严格来说不算私有协议)

• 基于 MQ 实现的 RPC(生产消费者模式,本质上这些 MQ 都是私有协议,比如 RocketMQ、Pulsar 等)

但我们需要在 RPC 调用的过程中在上下文里包含 Trace 时,通常都是将 TraceId 作为元数据进行传递。

对于 HTTP 来说就是 header、而其余的私有 TCP 协议通常也会提供一个元数据的结构用于存放一些非业务数据。

图片图片

图片图片

图片图片

比如在 OpenTelemetry-Go 的 sdk 中,会在一次 RPC 中对 Trace 数据进行埋点。

最终也是使用metadata metadata.MD来获取上下文。

在 Pulsar 中是将 TraceId 存放在 properties 中,也相当于是元数据。

┌──────┐│Client│└┬─────┘┌▽─────┐│Pulsar│└┬─────┘┌▽───┐ │gRPC│ └────┘

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { defer apiCounter.Add(ctx, 1) md, _ := metadata.FromIncomingContext(ctx) log.Printf("Received: %v, md: %v", in.GetName(), md) name, _ := os.Hostname() span := trace.SpanFromContext(ctx) span.SetAttributes(attribute.String("request.name", in.Name)) s.span(ctx) return &pb.HelloReply{Message: fmt.Sprintf("hostname:%s, in:%s, md:%v", name, in.Name, md)}, nil }

图片图片

图片图片

在这样一次调用中如果我们将Pulsar的properties和gRPCmeta 打印出来将会看到TraceID是如何进行传递的。

解决

回到这个问题本身,Trace在 Gin Server 端没有关联起来,明显就是 Gin 没有接收到上游的 TraceId,导致它认为是新的一次调用,从而会创建一个 Trace。

解决起来也很容易,只需要在启动 Gin 的时候传入一个 OTEL 提供的拦截器,在这个拦截器中 OTEL 的 sdk 会自动从 HTTP header 里解析出 TraceId 然后塞入到当前的 context 中,这样两个进程的 Trace 就可以关联起来了。

相关代码如下:

r := gin.New() r.Use(otelgin.Middleware("my-server"))

由于 Go 没有提供类似于 Java 的 javaagent 扩展,这类原本可以全自动打桩的代码都需要硬编码实现。

在这个otelgin实现的Middleware里会使用 HTTP header 来传输 context。

图片图片

图片图片

图片图片

本质上是操作 HTTP header 查询和写入 Trace

图片图片

会首先获取上游的 TraceID,这里的traceparentHeader也就是我们刚才看到的traceparent。

如果获取到了就会解析里面的TraceID,并生成当前的Context,这样这个 context 就会一直往后传递了。

流程与上文提到 gRPC 类似。

image.webpimage.webp

这是目前 otel-go-sdk 支持的自动打桩框架[1],目前看来还不太多,但常用的也都支持了。

总结

如何跨进程调的 Trace 信息都是通过网络传递的,只是对于不同的协议传输的细节也各不相同,但原理都是类似的。

图片图片

关键就是上面这两张图,进程 1 在调用进程 2 的时候将信息写入进去,进程 2 在收到请求的时候解析出 Trace,这两个步骤缺一不可。#Blog

引用链接

[1]自动打桩框架:https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation

来源:https://www.51cto.com/article/822994.html
上一篇梅赛德斯-AMG GT2 Edition W16发布:818马力纯燃油猛兽,限量30辆 下一篇天玑9500跑分曝光 iPhone16为新机让路价格滑铁卢!
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
罗福莉入选新一届35岁以下科技创新35人中国区名单
科技数码 · 2026-07-25

罗福莉入选新一届35岁以下科技创新35人中国区名单

2025年《麻省理工科技评论》“35岁以下科技创新35人”中国区名单在上海发布,罗福莉、姚顺宇等入选。罗福莉推动大模型从“能聊天”走向“能干活”,探索智能体演进;姚顺宇建立非厄米拓扑能带理论。本届AI+机器人领域入选者占四成。

美国科技巨头为AI投资年内裁员近14万人
科技数码 · 2026-07-25

美国科技巨头为AI投资年内裁员近14万人

美国科技巨头年内裁员近14万人,同时计划在AI基础设施上投入7250亿美元。裁员主要目的为AI投资腾出资金并纠正疫情期间过度招聘,市场对AI相关裁员反应负面,而AI初创公司正加速扩招,形成对比。

位AI Infra高管复盘WAIC:暴力美学触顶后求变?
科技数码 · 2026-07-25

位AI Infra高管复盘WAIC:暴力美学触顶后求变?

WAIC2026上,AIInfra行业关注点从算力规模转向推理效率与Token产出。Agent驱动Token消耗激增,AI工厂与Token工厂成为关键载体。效率竞争取代规模竞赛,玩家分层加速,具备全栈优化能力的头部厂商优势凸显。

显卡厂商封仓引发涨价 玩家面临高价购买
科技数码 · 2026-07-25

显卡厂商封仓引发涨价 玩家面临高价购买

显卡市场,恐怕又要迎来一波涨价潮了。过去两年,不少玩家咬咬牙买下的高价显卡,如今回头看,竟然成了抄底。但问题在于,硬件市场每一次涨价,最终买单的永远还是玩家。 业内消息显示,GDDR7显存价格出现了明显上涨,单颗2GB显存价格上涨接近20美元。按8GB显存规格计算,一张显卡的显存成本或将增加约542

OpenAI加入签署AI开源模型公开信,组织达35家
科技数码 · 2026-07-25

OpenAI加入签署AI开源模型公开信,组织达35家

7月25日,微软、英伟达等25家美国公司联署公开信支持开放权重AI模型,随后签署方增至35家,新增包括OpenAI等。开放权重模型可下载、修改、运行,能扩大创新、强化竞争并降低风险,避免AI收益集中于少数巨头。