通過Zipkin上報(bào)Go應(yīng)用數(shù)據(jù)
通過Zipkin為應(yīng)用埋點(diǎn)并上報(bào)鏈路數(shù)據(jù)至可觀測鏈路 OpenTelemetry 版后,可觀測鏈路 OpenTelemetry 版即可開始監(jiān)控應(yīng)用,您可以查看應(yīng)用拓?fù)洹⒄{(diào)用鏈路、異常事務(wù)、慢事務(wù)和SQL分析等一系列監(jiān)控?cái)?shù)據(jù)。本文介紹如何使用Zipkin為Go應(yīng)用埋點(diǎn)并上報(bào)數(shù)據(jù)。
為獲得更豐富的功能、更先進(jìn)的鏈路追蹤能力,以及最佳使用體驗(yàn),建議您使用OpenTelemetry協(xié)議將應(yīng)用接入可觀測鏈路 OpenTelemetry 版。我們?yōu)槟峁┝嗽敿?xì)的OpenTelemetry接入指南和最佳實(shí)踐,幫助您快速上手可觀測鏈路 OpenTelemetry 版。更多信息,請參見接入應(yīng)用。
ARMS應(yīng)用監(jiān)控針對Golang語言提供了商業(yè)化版本的自研探針,提供了無侵入的埋點(diǎn)能力,擁有更加豐富的功能和更高的穩(wěn)定性。詳細(xì)信息,請參見開始監(jiān)控Golang應(yīng)用。
前提條件
新版控制臺
登錄可觀測鏈路 OpenTelemetry 版控制臺,在左側(cè)導(dǎo)航欄單擊接入中心。
在開源框架區(qū)域單擊Zipkin卡片。
在彈出的Zipkin面板中選擇數(shù)據(jù)需要上報(bào)的地域。
說明初次接入的地域?qū)詣舆M(jìn)行資源初始化。
選擇連接方式,然后復(fù)制接入點(diǎn)信息。
若您的服務(wù)部署在阿里云上,且所屬地域與選擇的接入地域一致,推薦使用阿里云內(nèi)網(wǎng)方式,否則選擇公網(wǎng)方式。
舊版控制臺
在左側(cè)導(dǎo)航欄單擊集群配置,然后在右側(cè)頁面單擊接入點(diǎn)信息頁簽。
在頁面頂部選擇需要接入的地域,然后在集群信息區(qū)域打開顯示Token開關(guān)。
在客戶端采集工具區(qū)域單擊Zipkin。
在相關(guān)信息列中,獲取接入點(diǎn)信息。
說明如果應(yīng)用部署于阿里云生產(chǎn)環(huán)境,則選擇阿里云VPC網(wǎng)絡(luò)接入點(diǎn),否則選擇公網(wǎng)接入點(diǎn)。
背景信息
Zipkin是一款開源的分布式實(shí)時數(shù)據(jù)追蹤系統(tǒng)(Distributed Tracking System),由Twitter公司開發(fā)和貢獻(xiàn)。其主要功能是聚合來自各個異構(gòu)系統(tǒng)的實(shí)時監(jiān)控?cái)?shù)據(jù)。
代碼埋點(diǎn)
要通過Zipkin將Go應(yīng)用數(shù)據(jù)上報(bào)至可觀測鏈路 OpenTelemetry 版控制臺,首先需要完成埋點(diǎn)工作。
添加組件依賴。
[[constraint]] name = "github.com/openzipkin/zipkin-go" version = "0.1.1" [[constraint]] name = "github.com/gorilla/mux" version = "1.6.2"
創(chuàng)建Tracer。Tracer對象可以用來創(chuàng)建Span對象(記錄分布式操作時間)。Tracer對象還配置了上報(bào)數(shù)據(jù)的網(wǎng)關(guān)地址、本機(jī)IP、采樣頻率等數(shù)據(jù),您可以通過調(diào)整采樣率來減少因上報(bào)數(shù)據(jù)產(chǎn)生的開銷。
func getTracer(serviceName string, ip string) *zipkin.Tracer { // Create a reporter to be used by the tracer. reporter := httpreporter.NewReporter("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_aokcdqnxyz@123456ff_abcdef123@abcdef123/api/v2/spans") // Configure the local endpoint for the service. endpoint, _ := zipkin.NewEndpoint(serviceName, ip) // Configure the sampling strategy. sampler := zipkin.NewModuloSampler(1) // Initialize the tracer. tracer, _ := zipkin.NewTracer( reporter, zipkin.WithLocalEndpoint(endpoint), zipkin.WithSampler(sampler), ) return tracer; }
記錄請求數(shù)據(jù)。
// tracer can now be used to create spans. span := tracer.StartSpan("some_operation") // ... do some work ... span.Finish()
說明以上代碼用于記錄請求的根操作,如果需要記錄請求的上一步和下一步操作,則需要傳入上下文。示例:
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context())) // ... do some work ... childSpan.Finish()
可選:為了快速排查問題,您可以為某個記錄添加一些自定義標(biāo)簽,例如記錄是否發(fā)生錯誤、請求的返回值等;或自定義上報(bào)異常等特定信息。
添加自定義標(biāo)簽:
childSpan.Tag("http.status_code", statusCode)
自定義上報(bào)異常:
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context())) // ... do some work ... var events = make(map[string]string) events["event"] = "error" events["stack"] = "Runtime Exception: unable to find userid" jsonStr, err := json.Marshal(events) if err == nil { childSpan.Annotate(time.Now(), string(jsonStr)) } childSpan.Finish()
在分布式系統(tǒng)中發(fā)送RPC請求時會帶上Tracing數(shù)據(jù),包括TraceId、ParentSpanId、SpanId、Sampled等。您可以在HTTP請求中使用Extract/Inject方法在HTTP Request Headers上透傳數(shù)據(jù)。總體流程如下:
Client Span Server Span ┌──────────────────┐ ┌──────────────────┐ │ │ │ │ │ TraceContext │ Http Request Headers │ TraceContext │ │ ┌──────────────┐ │ ┌───────────────────┐ │ ┌──────────────┐ │ │ │ TraceId │ │ │ X-B3-TraceId │ │ │ TraceId │ │ │ │ │ │ │ │ │ │ │ │ │ │ ParentSpanId │ │ Inject │ X-B3-ParentSpanId │Extract │ │ ParentSpanId │ │ │ │ ├─┼─────────>│ ├────────┼>│ │ │ │ │ SpanId │ │ │ X-B3-SpanId │ │ │ SpanId │ │ │ │ │ │ │ │ │ │ │ │ │ │ Sampled │ │ │ X-B3-Sampled │ │ │ Sampled │ │ │ └──────────────┘ │ └───────────────────┘ │ └──────────────┘ │ │ │ │ │ └──────────────────┘ └──────────────────┘
說明目前Zipkin已有組件支持以HTTP、gRPC這兩種RPC協(xié)議透傳Context信息。
在客戶端調(diào)用Inject方法傳入Context信息。
req, _ := http.NewRequest("GET", "/", nil) // configure a function that injects a trace context into a request injector := b3.InjectHTTP(req) injector(sp.Context())
在服務(wù)端調(diào)用Extract方法解析Context信息。
req, _ := http.NewRequest("GET", "/", nil) b3.InjectHTTP(req)(sp.Context()) b.ResetTimer() _ = b3.ExtractHTTP(copyRequest(req))
快速入門
接下來以一個示例演示如何通過Zipkin上報(bào)Go應(yīng)用數(shù)據(jù)。
下載示例文件。
在utils.go文件中修改上報(bào)數(shù)據(jù)的網(wǎng)關(guān)地址(endpointURL)。
說明請將
<endpoint>
替換成可觀測鏈路 OpenTelemetry 版控制臺 頁面相應(yīng)客戶端和地域的接入點(diǎn)。獲取接入點(diǎn)信息的方法,請參見前提條件。安裝依賴包。
dep ensure
運(yùn)行測試程序。
go run main.go
在可觀測鏈路 OpenTelemetry 版控制臺的應(yīng)用列表頁面選擇目標(biāo)應(yīng)用,查看鏈路數(shù)據(jù)。
常見問題
問:為什么按照快速入門的步驟操作沒有上報(bào)數(shù)據(jù)?
答:請檢查運(yùn)行過程中是否有提示,并檢查endpoint_url的配置是否正確。例如,錯誤failed the request with status code 403
表明用戶名或密碼不正確。