zoukankan      html  css  js  c++  java
  • Jaeger全链路go实现,包含http和消息队列的链式传递

    Jaeger全链路go实现,包含http和消息队列的链式传递

    完整代码

    https://github.com/werbenhu/jaeger-go-demo
    同时,我提供了一个封装好的版本,更方便使用请参考
    https://github.com/werbenhu/jaeger-go

    本地链路

    本地链路,不涉及到trace-id跨服务器传递。
    通过opentracing.StartSpanFromContext即可完成,父span和子span关系
    如下代码:

    	tracer := opentracing.GlobalTracer()
    	//创建根span
    	rootSpan, rootCtx := opentracing.StartSpanFromContext(context.Background(), "root-span")
    	//...
    	//创建子span
    	subSpan, subCtx := opentracing.StartSpanFromContext(rootCtx, "sub-span")
    	//...
    	//...
    	subSpan.Finish()
    	//...
    	rootSpan.Finish()
    	//...
    
    http跨服务

    http跨服务需要解决trace-id传递的问题,参考下面的文档
    https://github.com/opentracing/opentracing-go
    https://opentracing.io/docs/overview/inject-extract/

    客户端请求的时候需要将trace-id放到header中

    	client := &http.Client{}
    	req, _ := http.NewRequest("GET","http://localhost:9002/server_two",nil)
    
    	// refer to https://github.com/opentracing/opentracing-go
    	// refer to https://opentracing.io/docs/overview/inject-extract/
    	tracer := opentracing.GlobalTracer()
    	// 生成一个请求的span
    	clientSpan, clientCtx := opentracing.StartSpanFromContext(ctx, "http-one-req")
    	carrier := opentracing.HTTPHeadersCarrier{}
    	tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, carrier)
    
    	// 将当前span的trace-id传递到http header中
    	for key, value := range carrier {
    		req.Header.Add(key, value[0])
    	}
    
    	// 发送请求
    	resp, _ := client.Do(req)
    	defer resp.Body.Close()
    	body, _ := ioutil.ReadAll(resp.Body)
    
    	//结束当前请求的span
    	clientSpan.Finish()
    

    服务器端要拿到客户端传递过来的trace-id,然后创建一个基于该trace-id的子span
    也就是认客户端为父

    	// 从http头中提取trace-id
    	// refer to https://github.com/opentracing/opentracing-go
    	// refer to https://opentracing.io/docs/overview/inject-extract/
    	carrier := opentracing.HTTPHeadersCarrier{}
    	carrier.Set("uber-trace-id", c.GetHeader("uber-trace-id"))
    
    	tracer := opentracing.GlobalTracer()
    	wireContext, err := tracer.Extract(
    		opentracing.HTTPHeaders,
    		opentracing.HTTPHeadersCarrier(c.Request.Header))
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// 由传递过来的trace-id作为父span
    	serverSpan := opentracing.StartSpan(
    		"server-two-http-root",
    		ext.RPCServerOption(wireContext))
    
    	ctx := opentracing.ContextWithSpan(context.Background(), serverSpan)
    	selfCall(ctx)
    
    		c.JSON(200, gin.H{
    			"message": "server two response",
    		})
    		serverSpan.Finish()
    
    消息队列实现全链路


    这里以nsq为例
    生产者将trace-id封装到msg中

    	tracer := opentracing.GlobalTracer()
    	clientSpan, clientCtx := opentracing.StartSpanFromContext(ctx, "nsq-one-req")
    	carrier := opentracing.HTTPHeadersCarrier{}
    	tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, carrier)
    
    	// 将trace-id封装到消息中,由消息队列,传给消费者
    	msg, _ := json.Marshal(carrier)
    	// 生产消息
    	Produce(TopicName, string(msg))
    
    	clientSpan.Finish()
    	return clientCtx
    

    消费者将trace-id取出,并创建基于该trace-id的子span,相当于认生产者为父

    // 消费者消息处理,处理server-one发送过来的消息
    func eventHandler(message string) error {
    	fmt.Printf("event msg:%s
    ", message)
    
    	jaeger := initJaeger("two1")
    	defer jaeger.Close()
    
    	// 读取消息中的trace-id
    	var carrier opentracing.HTTPHeadersCarrier
    	json.Unmarshal([]byte(message), &carrier)
    
    	tracer := opentracing.GlobalTracer()
    	wireContext, err := tracer.Extract(
    		opentracing.HTTPHeaders,
    		carrier)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// 由传递过来的trace-id作为父span
    	serverSpan := opentracing.StartSpan(
    		"nsq_two",
    		ext.RPCServerOption(wireContext))
    
    	ctx := opentracing.ContextWithSpan(context.Background(), serverSpan)
    	selfCall(ctx)
    	serverSpan.Finish()
    
    	return nil
    }
    
  • 相关阅读:
    RIA Animation test.
    深入浅出REST
    HTTP header中的 Cachecontrol
    Silverlight操纵html元素
    Comparing Azure storage and SQL Data Services
    SharePoint 2010 集成Window Live 认证遇到的问题 part 2
    SharePoint2010 此工作簿未存储在 Excel Services 应用程序 中受信任的位置,因此无法打开。
    SharePoint2010 使用Designer开发工作流 如何引用其他列表的查阅项
    SharePoint 2010 item级的权限控制
    Infopath 2010 如何设计虚线底框应用于合同中的输入框
  • 原文地址:https://www.cnblogs.com/werben/p/14362974.html
Copyright © 2011-2022 走看看