1. 分布式鏈路追蹤續(xù)集

        共 6121字,需瀏覽 13分鐘

         ·

        2021-10-09 18:05

        本文是 分布式鏈路追蹤 的續(xù)集。

        在上一文中提到為了統(tǒng)一各種分布式追蹤系統(tǒng)的實(shí)現(xiàn),CNCF (云原生計(jì)算基金會(huì))下的 OpenTracing 項(xiàng)目定義了一套分布式追蹤的標(biāo)準(zhǔn),可以使用 OpenTracing API 完成代碼的監(jiān)控埋點(diǎn),最后用戶自由選擇遵循 OpenTracing 標(biāo)準(zhǔn)的鏈路追蹤系統(tǒng),比如 jaeger 。

        但是現(xiàn)在訪問(wèn) OpenTracing 的 官網(wǎng)[1] ,可以發(fā)現(xiàn)官網(wǎng)提醒 OpenTracing 和 OpenCensus 已經(jīng)被合并成為 OpenTelemetry 。(在上文編寫時(shí)我未發(fā)現(xiàn)到,感謝 Donald Liu 大佬的提醒)

        cncf[2] 上也可以發(fā)現(xiàn) OpenTracing 已經(jīng)被 Archived 了

        相應(yīng)地,OpenTelemetry 已經(jīng)正式成為了 CNCF 的孵化項(xiàng)目 參考[3]

        Both OpenTracing and OpenCensus will be further deprecated in the coming weeks, with OpenTracing being formally archived by the CNCF TOC.

        緣由

        參考[4]

        在 APM (Application Performance Monitoring) 領(lǐng)域,或者說(shuō)微服務(wù)的可觀察性方面包括有分布式鏈路追蹤,指標(biāo)監(jiān)控和日志。

        OpenTracing 是最早為分布式追蹤制定了一套平臺(tái)無(wú)關(guān)、廠商無(wú)關(guān)的協(xié)議標(biāo)準(zhǔn)的項(xiàng)目,并以此成為了 CNCF 的孵化項(xiàng)目。

        在之后,谷歌牽頭,微軟加入,創(chuàng)建了 OpenCensus 項(xiàng)目統(tǒng)一 Metrics 基礎(chǔ)指標(biāo)監(jiān)控的使用方式,還做了 OpenTracing 的老本行:分布式追蹤。

        一山不容二虎,OpenTracing 和 OpenCensus 愈打愈烈,對(duì)我們用戶來(lái)講,實(shí)在是太不友好了。

        然后 OpenTelemetry 橫空出世了,OpenTracing 和 OpenCensus 既然都這么好,干脆你們合并起來(lái)吧,我 OpenTelemetry 來(lái)兼容你們。

        OpenTelemetry 的自身定位十分明確:數(shù)據(jù)采集和標(biāo)準(zhǔn)規(guī)范的統(tǒng)一,對(duì)于數(shù)據(jù)如何去使用、存儲(chǔ)、展示、告警,官方是不涉及的。

        OpenTelemetry 的終極目標(biāo)十分偉大:實(shí)現(xiàn) Metrics、Tracing、Logging 的融合及大一統(tǒng),作為 APM 的數(shù)據(jù)采集終極解決方案。

        然后就是現(xiàn)在的故事了,OpenTelemetry 正式成為 CNCF 的孵化項(xiàng)目,OpenTracing 和 OpenCensus 不再維護(hù)。

        兼容性

        這個(gè)放心,大部分的知識(shí)點(diǎn)定義還是一致的 (如數(shù)據(jù)模型:Trace, Span, SpanContext) ,但是 API 的使用會(huì)有所區(qū)別,詳細(xì)可以查看 OpenTelemetry 規(guī)范文檔[5]

        承接上文

        我們現(xiàn)在對(duì)上文的 OpenTracing API 的代碼做出修改,擁抱 OpenTelemetry 吧!

        安裝 OpenTelemetry for Go 依賴

        go?get?go.opentelemetry.io/[email protected]?go.opentelemetry.io/otel/[email protected]?go.opentelemetry.io/otel/exporters/stdout/[email protected]?go.opentelemetry.io/otel/[email protected]

        安裝 OpenTelemetry for jaeger 依賴

        go?get?-u?go.opentelemetry.io/otel/exporters/jaeger

        OpenTelemetry 官方為多種開(kāi)源框架提供了開(kāi)箱即用的 Instrumentation Packages ,如 gin , beego , mux , go-kit 等,當(dāng)然也支持 net/http 標(biāo)準(zhǔn)庫(kù) ,更多可瀏覽opentelemetry-go-contrib[6]

        我們使用的是 net/http 標(biāo)準(zhǔn)庫(kù),所以直接導(dǎo)入 otelhttp

        go?get?go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

        main.go 修改如下:

        package?main

        import?(
        ?"fmt"
        ?"log"
        ?"math/rand"
        ?"net/http"
        ?"time"

        ?"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
        ?"go.opentelemetry.io/otel"
        ?"go.opentelemetry.io/otel/attribute"
        ?"go.opentelemetry.io/otel/exporters/jaeger"
        ?"go.opentelemetry.io/otel/propagation"
        ?"go.opentelemetry.io/otel/sdk/resource"
        ?tracesdk?"go.opentelemetry.io/otel/sdk/trace"
        ?semconv?"go.opentelemetry.io/otel/semconv/v1.4.0"
        ?"go.opentelemetry.io/otel/trace"
        )

        func?init()?{
        ?exp,?err?:=?jaeger.New(jaeger.WithAgentEndpoint())
        ?if?err?!=?nil?{
        ??panic(err)
        ?}
        ?tp?:=?tracesdk.NewTracerProvider(
        ??tracesdk.WithSampler(tracesdk.AlwaysSample()),
        ??tracesdk.WithBatcher(exp),
        ??tracesdk.WithResource(resource.NewWithAttributes(
        ???semconv.SchemaURL,
        ???semconv.ServiceNameKey.String("opentelemetry-example"),?//?服務(wù)名
        ???semconv.ServiceVersionKey.String("0.0.1"),
        ??)),
        ?)
        ?otel.SetTracerProvider(tp)
        ?otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{},?propagation.Baggage{}))
        }

        func?main()?{
        ?port?:=?8080
        ?addr?:=?fmt.Sprintf(":%d",?port)
        ?mux?:=?http.NewServeMux()
        ?mux.HandleFunc("/",?indexHandler)
        ?mux.Handle("/home",?otelhttp.NewHandler(http.HandlerFunc(homeHandler),?"請(qǐng)求?/home"))
        ?mux.Handle("/async",?otelhttp.NewHandler(http.HandlerFunc(serviceHandler),?"請(qǐng)求?/async"))
        ?mux.Handle("/service",?otelhttp.NewHandler(http.HandlerFunc(serviceHandler),?"請(qǐng)求?/service"))
        ?mux.Handle("/db",?otelhttp.NewHandler(http.HandlerFunc(dbHandler),?"請(qǐng)求?/db"))
        ?fmt.Printf("http://localhost:%d\n",?port)
        ?log.Fatal(http.ListenAndServe(addr,?mux))
        }

        //?主頁(yè)?Html
        func?indexHandler(w?http.ResponseWriter,?r?*http.Request)?{
        ?w.Write([]byte(`?點(diǎn)擊開(kāi)始發(fā)起請(qǐng)求?`))
        }

        func?homeHandler(w?http.ResponseWriter,?r?*http.Request)?{
        ?w.Write([]byte("開(kāi)始請(qǐng)求...\n"))

        ?ctx?:=?r.Context()
        ?span :=?trace.SpanFromContext(ctx)
        ?defer?span.End()

        ?//?發(fā)起異步請(qǐng)求
        ?asyncReq,?_?:=?http.NewRequest("GET",?"http://localhost:8080/async",?nil)
        ?//?傳遞span的上下文信息
        ?//?將關(guān)于本地追蹤調(diào)用的span context,設(shè)置到http?header上,并傳遞出去
        ?otel.GetTextMapPropagator().Inject(ctx,
        ??propagation.HeaderCarrier(asyncReq.Header),
        ?)
        ?go?func()?{
        ??if?_,?err?:=?http.DefaultClient.Do(asyncReq);?err?!=?nil?{
        ???span.RecordError(err)
        ???span.SetAttributes(
        ????attribute.String("請(qǐng)求?/async?error",?err.Error()),
        ???)
        ??}
        ?}()

        ?time.Sleep(time.Duration(rand.Intn(200))?*?time.Millisecond)

        ?//?發(fā)起同步請(qǐng)求
        ?syncReq,?_?:=?http.NewRequest("GET",?"http://localhost:8080/service",?nil)
        ?otel.GetTextMapPropagator().Inject(ctx,
        ??propagation.HeaderCarrier(syncReq.Header),
        ?)
        ?if?_,?err?:=?http.DefaultClient.Do(syncReq);?err?!=?nil?{
        ??span.RecordError(err)
        ??span.SetAttributes(
        ???attribute.String("請(qǐng)求?/service?error",?err.Error()),
        ??)
        ?}
        ?w.Write([]byte("請(qǐng)求結(jié)束!"))
        }

        //?模擬業(yè)務(wù)請(qǐng)求
        func?serviceHandler(w?http.ResponseWriter,?r?*http.Request)?{
        ?//?通過(guò)http?header,提取span元數(shù)據(jù)信息
        ?span :=?trace.SpanFromContext(
        ??otel.GetTextMapPropagator().Extract(r.Context(),?propagation.HeaderCarrier(r.Header)),
        ?)
        ?defer?span.End()

        ?dbReq,?_?:=?http.NewRequest("GET",?"http://localhost:8080/db",?nil)
        ?otel.GetTextMapPropagator().Inject(r.Context(),?propagation.HeaderCarrier(dbReq.Header))
        ?if?_,?err?:=?http.DefaultClient.Do(dbReq);?err?!=?nil?{
        ??span.RecordError(err)
        ??span.SetAttributes(
        ???attribute.String("請(qǐng)求?/db?error",?err.Error()),
        ??)
        ?}

        ?time.Sleep(time.Duration(rand.Intn(200))?*?time.Millisecond)
        }

        //?模擬DB調(diào)用
        func?dbHandler(w?http.ResponseWriter,?r?*http.Request)?{
        ?//?通過(guò)http?header,提取span元數(shù)據(jù)信息
        ?span :=?trace.SpanFromContext(
        ??otel.GetTextMapPropagator().Extract(r.Context(),?propagation.HeaderCarrier(r.Header)),
        ?)
        ?defer?span.End()

        ?time.Sleep(time.Duration(rand.Intn(200))?*?time.Millisecond)
        }

        同樣的部署到集群中

        kubectl?apply?-f?https://raw.githubusercontent.com/togettoyou/jaeger-example/master/jaeger-example-opentelemetry.yaml?-n?observability

        訪問(wèn)后觀察 Jaeger UI 可以發(fā)現(xiàn)調(diào)用鏈和之前的也一致,包含 5 個(gè) Span

        具體 Span 信息

        參考資料

        [1]

        官網(wǎng): https://opentracing.io/

        [2]

        cncf: https://www.cncf.io/archived-projects/

        [3]

        參考: https://www.cncf.io/blog/2021/08/26/opentelemetry-becomes-a-cncf-incubating-project/

        [4]

        參考: https://github.com/open-telemetry/docs-cn/blob/main/OT.md

        [5]

        OpenTelemetry 規(guī)范文檔: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md

        [6]

        opentelemetry-go-contrib: https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/README.md


        瀏覽 94
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 做爱在线观看网站 | 爱搞逼综合网 | 看全色黄大色大片免费 | 精品无码国产污污污免费网站 | 操逼网1234 |