W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
分布式鏈路跟蹤( ?Distributed Tracing
? )的概念最早是由?Google
?提出來(lái)的,發(fā)展至今技術(shù)已經(jīng)比較成熟,也是有一些協(xié)議標(biāo)準(zhǔn)可以參考。目前在?Tracing
?技術(shù)這塊比較有影響力的是兩大開(kāi)源技術(shù)框架:?Netflix
?公司開(kāi)源的?OpenTracing
?和?Google
?開(kāi)源的?OpenCensus
?。兩大框架都擁有比較高的開(kāi)發(fā)者群體。為形成統(tǒng)一的技術(shù)標(biāo)準(zhǔn),兩大框架最終磨合成立了?OpenTelemetry
?項(xiàng)目,簡(jiǎn)稱?otel
?。具體可以參考:
因此,我們的?Tracing
?技術(shù)方案以?OpenTelemetry
?為實(shí)施標(biāo)準(zhǔn),協(xié)議標(biāo)準(zhǔn)的一些Golang實(shí)現(xiàn)開(kāi)源項(xiàng)目:
https://github.com/open-telemetry/opentelemetry-go
https://github.com/open-telemetry/opentelemetry-go-contrib
其他第三方的框架和系統(tǒng)(如?Jaeger/Prometheus/Grafana
?等)也會(huì)按照標(biāo)準(zhǔn)化的規(guī)范來(lái)對(duì)接?OpenTelemetry
?,使得系統(tǒng)的開(kāi)發(fā)和維護(hù)成本大大降低。
我們先看看?OpenTelemetry
?的架構(gòu)圖,我們這里不會(huì)完整介紹,只會(huì)介紹其中大家常用的幾個(gè)概念。關(guān)于?OpenTelemetry
?的內(nèi)部技術(shù)架構(gòu)設(shè)計(jì)介紹,可以參考 ?OpenTelemetry
?架構(gòu) ,關(guān)于語(yǔ)義約定請(qǐng)參考:https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md
主要負(fù)責(zé)創(chuàng)建?Tracer
?,一般是需要第三方的分布式鏈路跟蹤管理平臺(tái)提供具體的實(shí)現(xiàn)。默認(rèn)情況是一個(gè)空的?TracerProvider (NoopTracerProvider)
?,雖然也能創(chuàng)建?Tracer
?但是內(nèi)部其實(shí)不會(huì)執(zhí)行具體的數(shù)據(jù)流傳輸邏輯。
?Tracer
?表示一次完整的追蹤鏈路,?tracer
?由一個(gè)或多個(gè)?span
?組成。下圖示例表示了一個(gè)由8個(gè)?span
?組成的?tracer
?:
[Span A] ←←←(the root span)
|
+------+------+
| |
[Span B] [Span C] ←←←(Span C is a `ChildOf` Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
↑
↑
↑
(Span G `FollowsFrom` Span F)
時(shí)間軸的展現(xiàn)方式會(huì)更容易理解:
––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
[Span A···················································]
[Span B··············································]
[Span D··········································]
[Span C········································]
[Span E·······] [Span F··] [Span G··] [Span H··]
我們通常通過(guò)以下方式創(chuàng)建一個(gè)?Tracer
?:
gtrace.NewTracer(tracerName)
?Span
?是一條追蹤鏈路中的基本組成要素,一個(gè)?span
?表示一個(gè)獨(dú)立的工作單元,比如可以表示一次函數(shù)調(diào)用,一次?http
?請(qǐng)求等等。?span
?會(huì)記錄如下基本要素:
operation name
?)K/V
?形式的?Tags
?K/V
?形式的?Logs
?SpanContext
??Span
?是這么多對(duì)象中使用頻率最高的,因此創(chuàng)建?Span
?也非常簡(jiǎn)便,例如:
gtrace.NewSpan(ctx, spanName, opts...)
?Attributes
?以?K/V
?鍵值對(duì)的形式保存用戶自定義標(biāo)簽,主要用于鏈路追蹤結(jié)果的查詢過(guò)濾。例如:http.method="GET",http.status_code=200
?。其中?key
?值必須為字符串,?value
?必須是字符串,布爾型或者數(shù)值型。 ?span
?中的?Attributes
?僅自己可見(jiàn),不會(huì)隨著?SpanContext
?傳遞給后續(xù)?span
?。 設(shè)置?Attributes
?方式例如:
span.SetAttributes(
label.String("http.remote", conn.RemoteAddr().String()),
label.String("http.local", conn.LocalAddr().String()),
)
?Events
?與?Attributes
?類似,也是?K/V
?鍵值對(duì)形式。與?Attributes
?不同的是,?Events
?還會(huì)記錄寫(xiě)入?Events
?的時(shí)間,因此?Events
?主要用于記錄某些事件發(fā)生的時(shí)間。?Events
?的?key
?值同樣必須為字符串,但對(duì)?value
?類型則沒(méi)有限制。例如:
span.AddEvent("http.request", trace.WithAttributes(
label.Any("http.request.header", headers),
label.Any("http.request.baggage", gtrace.GetBaggageMap(ctx)),
label.String("http.request.body", bodyContent),
))
?SpanContext
?攜帶著一些用于跨服務(wù)通信的(跨進(jìn)程)數(shù)據(jù),主要包含:
span
?的信息,比如:?span_id
?, ?trace_id
?。Baggage
?-為整條追蹤連保存跨服務(wù)(跨進(jìn)程)的?K/V
?格式的用戶自定義數(shù)據(jù)。?Baggage
? 與 ?Attributes
? 類似,也是 ?K/V
? 鍵值對(duì)。與Attributes
不同的是:key
?跟?value
?都只能是字符串格式Baggage
?不僅當(dāng)前?span
?可見(jiàn),其會(huì)隨著?SpanContext
?傳遞給后續(xù)所有的子?span
?。要小心謹(jǐn)慎的使用?Baggage
- 因?yàn)樵谒械?span
?中傳遞這些?K,V
?會(huì)帶來(lái)不小的網(wǎng)絡(luò)和?CPU
?開(kāi)銷(xiāo)。?Propagator
?傳播器用于端對(duì)端的數(shù)據(jù)編碼/解碼,例如:?Client
?到?Server
?端的數(shù)據(jù)傳輸,?TraceId
?、?SpanId
?和?Baggage
?也是需要通過(guò)傳播器來(lái)管理數(shù)據(jù)傳輸。業(yè)務(wù)端開(kāi)發(fā)者往往對(duì)?Propagator
?無(wú)感知,只有中間件/攔截器的開(kāi)發(fā)者需要知道它的作用。?OpenTelemetry
?的標(biāo)準(zhǔn)協(xié)議實(shí)現(xiàn)庫(kù)提供了常用的?TextMapPropagator
?,用于常見(jiàn)的文本數(shù)據(jù)端到端傳輸。此外,為保證?TextMapPropagator
?中的傳輸數(shù)據(jù)兼容性,不應(yīng)當(dāng)帶有特殊字符,具體請(qǐng)參考:https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md
?GoFrame
?框架通過(guò)?gtrace
模塊使用了以下傳播器對(duì)象,并全局設(shè)置到了?OpenTelemetry
?中:
// defaultTextMapPropagator is the default propagator for context propagation between peers.
defaultTextMapPropagator = propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
)
?GoFrame
?的核心組件都已經(jīng)全面支持?OpenTelemetry
?標(biāo)準(zhǔn),并且自動(dòng)開(kāi)啟了鏈路跟蹤特性,開(kāi)發(fā)者無(wú)需顯示調(diào)用、使用無(wú)感知。在沒(méi)有注入外部?TracerProvider
?的情況下,框架會(huì)使用默認(rèn)的?TracerProvider
?,該?TracerProvider
?只會(huì)自動(dòng)創(chuàng)建?TraceID
?及?SpanID
?,并不會(huì)執(zhí)行復(fù)雜邏輯。
包括但不限于以下核心組件:
Http Client
??HTTP
?客戶端自動(dòng)啟用了鏈路跟蹤特性。
Http Server
??HTTP
?服務(wù)端自動(dòng)啟用了鏈路跟蹤特性。
gRPC Client
??gRPC
?客戶端自動(dòng)啟用了鏈路跟蹤特性。
gRPC Server
??gRPC
?服務(wù)端自動(dòng)啟用了鏈路跟蹤特性。
Logging
?日志內(nèi)容中需要注入當(dāng)前請(qǐng)求的?TraceId
?,以方便通過(guò)日志快速查找定位問(wèn)題點(diǎn)。該特性是由?glog
?組件實(shí)現(xiàn),這需要開(kāi)發(fā)者在輸出日志的時(shí)候調(diào)用?Ctx
?鏈?zhǔn)讲僮鞣椒▽?context.Context
?上下文變量傳遞到當(dāng)前輸出日志操作鏈路中,沒(méi)有傳遞?context.Context
?上下文變量,就會(huì)丟失日志內(nèi)容中的?TraceId
?。
ORM
?數(shù)據(jù)庫(kù)的執(zhí)行是很重要的鏈路環(huán)節(jié),?Orm
?組件需要將自身的執(zhí)行情況投遞到鏈路中,作為執(zhí)行鏈路的一部分。
Redis
??Redis
?的執(zhí)行也是很重要的鏈路環(huán)節(jié),?Redis
?需要將自身的執(zhí)行情況投遞到鏈路中,作為執(zhí)行鏈路的一部分。
Utils
?對(duì)于?Tracing
?特性的管理需要做一定的封裝,主要考慮的是可擴(kuò)展性和易用性兩方面。該封裝由?gtrace
?模塊實(shí)現(xiàn),文檔地址:https://pkg.go.dev/github.com/gogf/gf/v2/net/gtrace
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: