在微服务的提取载体中找不到SpanContext [英] SpanContext not found in Extract carrier in microservice

查看:731
本文介绍了在微服务的提取载体中找不到SpanContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现基于Go的微服务系统.我有两项服务,我尝试InjectExtract跨度数据.

在我的第一项服务中,我有:

func (apitracer apiTracer) validatemail(res http.ResponseWriter, req *http.Request) {

    validateEmailSpan := apitracer.tracer.StartSpan("Validate Email")

    apitracer.tracer.Inject(
            validateEmailSpan.Context(),
            opentracing.HTTPHeaders,
            opentracing.HTTPHeadersCarrier(req.Header))
        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
        resp, err := httpClient.Do(req)

服务二:

wireContext, err := opentracing.GlobalTracer().Extract(
        opentracing.HTTPHeaders,
        opentracing.HTTPHeadersCarrier(req.Header))

我收到以下错误:

在提取载体中找不到SpanContext

如果转储log.Println("Form values : ", req.Header.Get("Uber-Trace-Id")),则会得到与Service-One相同的正确Uber-Trace-Id值.

请求标头设置为application/x-www-form-urlencoded 此处建议

@eminlala之后

Tracer初始化步骤.

type apiTracer struct {
    tracer opentracing.Tracer
}

// Tracing function
func startTracing(service string) opentracing.Tracer {

    cfg := config.Configuration{
        Sampler: &config.SamplerConfig{
            Type:  "const",
            Param: 1,
        },
        Reporter: &config.ReporterConfig{
            LogSpans:            true,
            BufferFlushInterval: 1 * time.Second,
        },
    }
    tracer, _, _ := cfg.New(
        service,
        config.Logger(jaeger.StdLogger),
    )
    opentracing.SetGlobalTracer(tracer)

    return tracer
}

解决方案

查看您的代码,我发现您在创建跟踪器时错过了添加InjectorExtractor选项的机会.它应该看起来像这样:

zipkinPropagator := zipkin.NewZipkinB3HTTPHeaderPropagator()

tracer, _, err := cfg.New(
        e.ServiceName, config.Logger(jaeger.StdLogger), config.ZipkinSharedRPCSpan(true),
        config.Injector(opentracing.HTTPHeaders, zipkinPropagator),
        config.Extractor(opentracing.HTTPHeaders, zipkinPropagator))

opentracing.SetGlobalTracer(tracer)

ZipkinPropagator来自github.com/uber/jaeger-client-go/zipkin软件包.

您应该尝试ZipkinPropagator,因为它的配置比普通的HTTPHeaderPropagator少. ZipkinPropagator接收的参数较少,但灵活性也较差.同样,您从Extract方法收到的错误属于opentracing.ErrSpanContextNotFound类型. ZipkinPropagatorExtract方法不太复杂,因为它仅在发送opentracing.ErrSpanContextNotFound错误(当carrier.TraceID()==0时)之前检查TraceID.

您也可以使用HTTPHeaderPropagator,但是它的设置稍微复杂一些,并且Extract方法会在发送opentracing.ErrSpanContextNotFound错误之前检查除TraceID以外的其他内容(检查debugID和从HeadersConfig中提取的baggage).

回顾您之前关于opentracing问题,如果未包含InjectorExtractor设置,则可能是为什么在目标服务中提取跨度上下文时未找到uber-trace-id的问题.

I am trying to implement a Go-based microservice system. I have two service and I try to Inject and Extract span data.

In my first service, I have:

func (apitracer apiTracer) validatemail(res http.ResponseWriter, req *http.Request) {

    validateEmailSpan := apitracer.tracer.StartSpan("Validate Email")

    apitracer.tracer.Inject(
            validateEmailSpan.Context(),
            opentracing.HTTPHeaders,
            opentracing.HTTPHeadersCarrier(req.Header))
        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
        resp, err := httpClient.Do(req)

In service two :

wireContext, err := opentracing.GlobalTracer().Extract(
        opentracing.HTTPHeaders,
        opentracing.HTTPHeadersCarrier(req.Header))

I get following error :

SpanContext not found in Extract carrier

If I dump log.Println("Form values : ", req.Header.Get("Uber-Trace-Id")), I get proper Uber-Trace-Id value which is same as Service-One.

Request headers are set to application/x-www-form-urlencoded as suggested here

Edit : After @eminlala

Tracer init step.

type apiTracer struct {
    tracer opentracing.Tracer
}

// Tracing function
func startTracing(service string) opentracing.Tracer {

    cfg := config.Configuration{
        Sampler: &config.SamplerConfig{
            Type:  "const",
            Param: 1,
        },
        Reporter: &config.ReporterConfig{
            LogSpans:            true,
            BufferFlushInterval: 1 * time.Second,
        },
    }
    tracer, _, _ := cfg.New(
        service,
        config.Logger(jaeger.StdLogger),
    )
    opentracing.SetGlobalTracer(tracer)

    return tracer
}

解决方案

Looking at your code I see that you missed to add Injector and Extractor options when creating the tracer. It should look something like this:

zipkinPropagator := zipkin.NewZipkinB3HTTPHeaderPropagator()

tracer, _, err := cfg.New(
        e.ServiceName, config.Logger(jaeger.StdLogger), config.ZipkinSharedRPCSpan(true),
        config.Injector(opentracing.HTTPHeaders, zipkinPropagator),
        config.Extractor(opentracing.HTTPHeaders, zipkinPropagator))

opentracing.SetGlobalTracer(tracer)

ZipkinPropagator is from github.com/uber/jaeger-client-go/zipkin package.

You should try ZipkinPropagator because it has less configuration than the plain HTTPHeaderPropagator. ZipkinPropagator receives less parameters, but it's also less flexible. Also, the error you received is from the Extract method is of type opentracing.ErrSpanContextNotFound. Extract method for ZipkinPropagator is less complex as it only check for the TraceID before sending the opentracing.ErrSpanContextNotFound error (when carrier.TraceID()==0).

You can use the HTTPHeaderPropagator as well, but it has a bit more complex setup, and Extract method checks for more things other than TraceID before sending the opentracing.ErrSpanContextNotFound error (checks for debugID and baggage that is extracted from HeadersConfig).

EDIT:

Looking back at your previous question regarding opentracing, if you haven't included Injector and Extractor setup, that might have been the problem why uber-trace-id was not found when extracting the span context in the target service.

这篇关于在微服务的提取载体中找不到SpanContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆