腾讯mini项目-【指标监控服务重构】2023-08-01

今日已办

合并 Traefik 和 Profile 的 Trace

Traceparent Header 理解有误

Trace Context (w3.org)

故需要解析 TraceHeader 才能获取trace_id、parent_id

go 复制代码
func (profileCtx *ProfileContext) UnpackKafkaMessage(ctx context.Context) (needBreak bool, tpsStatus string, contextErr error) {
	var traceID trace.TraceID
	var parentID trace.SpanID
	headers := profileCtx.msg.Headers
	for _, h := range headers {
		key := h.Key
		value := string(h.Value)
		if key == "Traceparent" {
            // eg: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
			split := strings.Split(value, "-")
			traceID, _ = trace.TraceIDFromHex(split[1])
			parentID, _ = trace.SpanIDFromHex(split[2])
			break
		}
	}
	log.Logger.Info("[UnpackKafkaItem] parse header traceparent",
		zap.String("traceId", traceID.String()),
		zap.String("parentID", parentID.String()),
	)
	//otel.GetTextMapPropagator().Extract(profileCtx.Ctx, header)
	ctx = trace.ContextWithRemoteSpanContext(ctx,
		trace.NewSpanContext(trace.SpanContextConfig{
			TraceID: traceID,
		}))
	var span trace.Span
	profileCtx.Ctx, span = consumerTracer.Start(ctx, "UnpackKafkaMessage")
	//profileCtx.Ctx, span = consumerTracer.Start(profileCtx.Ctx, "UnpackKafkaMessage")
	defer span.End()
	// ...
	return
}

调研上下文传递 Propagator

参考 passthrough

Venus 服务中初始化 TextMapPropagator

go 复制代码
func initPassthroughGlobals() {
	// We explicitly DO NOT set the global TracerProvider using otel.SetTracerProvider().
	// The unset TracerProvider returns a "non-recording" span, but still passes through context.
	log.Logger().Info("Register a global TextMapPropagator, but do not register a global TracerProvider to be in \"passthrough\" mode.")
	log.Logger().Info("The \"passthrough\" mode propagates the TraceContext and Baggage, but does not record spans.")
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
}

再根据 Fiber 的 Context 和 Header 来解包出 Context ,创建 Span

go 复制代码
var (
	traceparent    string
	producerTracer = otel.Tracer("venus-producer",
		trace.WithInstrumentationAttributes(attribute.String("venus.work", "producer")))
)

func SplitAndValidate(c *fiber.Ctx) error {
	traceparent = c.Get("Traceparent", "default")
	log.Logger().Info("Traceparent", zap.Any("Traceparent", traceparent))
	log.Logger().Debug("split and validate", zap.String("client", c.IP()), zap.String("agent", string(c.Context().UserAgent())))
	header := make(propagation.HeaderCarrier)
	for k, v := range c.GetReqHeaders() {
		header.Set(k, v)
	}
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	ctx := otel.GetTextMapPropagator().Extract(c.Context(), header)
	_, span := producerTracer.Start(ctx, "SplitAndValidate")
	defer span.End()
	// ...
	return c.Next()
}

Venus中注入,ctx 为 Kafka 的 WriteMessages 的,携带 TraceParentHeader

【感觉没有必要,确实我移除这部分代码正常运行】

  1. 因为 kafka 没有上下文机制,是使用 header 来传播 TraceParent
  2. TraceParent 包含了 trace-id、parent-id共4个字段
  3. Extract方法应该可以根据这个TraceParent的值来解析出tracespan的关系

以相同的方式在 Profile 中处理,关于traceID、parentID的代码就可以移除了

现在的 venus 和 profile 是同一级,是因为 traefik 传播的 traceparent 没有修改,parent-id 是相同的,应该需要 venus 将最后一个 span 的 span_id 更新到 traceparent 的 parent-id 的部分,然后再用 kafka 的 header 传播下来

明日待办

  1. 组长会议汇报进度和问题
相关推荐
光头闪亮亮1 天前
电子发票解析工具-golang服务端开发案例详解
go
现在,此刻1 天前
clickhouse和pgSql跨库查询方案对比
数据库·sql·clickhouse·性能优化
擎创夏洛克AIOps1 天前
数据存储新势力:Doris如何挑战ClickHouse的霸主地位?
clickhouse
Mgx1 天前
从“CPU 烧开水“到优雅暂停:Go 里 sync.Cond 的正确打开方式
go
说私域1 天前
社群经济下开源链动2+1模式AI智能名片S2B2C商城小程序的信任重构机制研究
人工智能·小程序·重构
GM_8282 天前
从0开始在Go当中使用Apache Thrift框架(万字讲解+图文教程+详细代码)
rpc·go·apache·thrift
天若有情6732 天前
新闻通稿 | 软件产业迈入“智能重构”新纪元:自主进化、人机共生与责任挑战并存
服务器·前端·后端·重构·开发·资讯·新闻
BJ_Bonree2 天前
圆桌论坛精华实录 | AI是重构运维逻辑的颠覆性革命?博睿数据与行业大咖亲授“AI+可观测性”的破局之道
运维·人工智能·重构
终端域名2 天前
从 Grok 4 多智能体协同到 RAG 范式革命:2025 年 AI 工作流的技术重构生成
人工智能·重构
Kratos开源社区2 天前
别卷 LangChain 了!Blades AI 框架让 Go 开发者轻松打造智能体
go·agent·ai编程