Go微服務(wù)架構(gòu)實(shí)戰(zhàn) 下篇:1. gRPC + Opentracing + Zipkin實(shí)現(xiàn)分布式鏈路追蹤系統(tǒng)

Go微服務(wù)架構(gòu)實(shí)戰(zhàn)-【公粽號(hào):堆棧future】

原文
Go微服務(wù)架構(gòu)實(shí)戰(zhàn)目錄

1. 微服務(wù)架構(gòu)上篇

1. grpc技術(shù)介紹

2. grpc+protobuf+網(wǎng)關(guān)實(shí)戰(zhàn)

3. etcd技術(shù)介紹

4. 基于etcd的服務(wù)發(fā)現(xiàn)與注冊(cè)

5. 基于etcd的分布式鎖實(shí)戰(zhàn)

2. 微服務(wù)架構(gòu)中篇

1. k8s架構(gòu)介紹

2. 基于k8s的容器化部署

3. 基于k8s的Deployment工作負(fù)載

4. 基于k8s的ingress實(shí)戰(zhàn)

5. 基于ingress和service實(shí)現(xiàn)灰度發(fā)布

6. 常見的服務(wù)治理策略

3. 微服務(wù)架構(gòu)下篇

分布式鏈路追蹤實(shí)戰(zhàn)

干貨:


什么是APM

什么是Opentracing

什么是SpanID

什么是TraceID

基于zipkin構(gòu)建鏈路追蹤


1. 什么是APM

APM(Application Performance Management,即應(yīng)用性能管理,在分布式領(lǐng)域也稱為分布式跟蹤管理)對(duì)企業(yè)的應(yīng)用系統(tǒng)進(jìn)行實(shí)時(shí)監(jiān)控,它是用于實(shí)現(xiàn)對(duì)應(yīng)用程序性能管理和故障管理的系統(tǒng)化的解決方案。

APM核心功能:

  • 服務(wù)調(diào)用跟蹤
  • 應(yīng)用系統(tǒng)存活檢測(cè)
  • 監(jiān)控告警

開源APM管理工具:

  • ZipKin
  • PinPoint
  • SkyWalking
  • Prometheus

我們這篇文章主要是講解APM的核心功能之一:服務(wù)調(diào)用跟蹤,用到的工具是ZipKin,本來想用Prometheus搭建一個(gè)監(jiān)控平臺(tái),想來想去比較簡單,大家直接在本地就可以搭建單機(jī)版的監(jiān)控平臺(tái)。

2. 什么是Opentracing

OpenTracing通過提供平臺(tái)無關(guān)、廠商無關(guān)的API,使得開發(fā)人員能夠方便的添加(或更換)追蹤系統(tǒng)的實(shí)現(xiàn)。

不過OpenTracing并不是標(biāo)準(zhǔn)。因?yàn)镃NCF不是官方標(biāo)準(zhǔn)機(jī)構(gòu),但是它的目標(biāo)是致力為分布式追蹤創(chuàng)建更標(biāo)準(zhǔn)的API和工具。

3. 什么是TraceID

一個(gè)trace代表了一個(gè)事務(wù)或者流程在(分布式)系統(tǒng)中的執(zhí)行過程,而這個(gè)過程會(huì)有唯一ID去標(biāo)識(shí),這個(gè)唯一ID就是Trace ID,通俗解釋就是一個(gè)API請(qǐng)求的完整調(diào)用流程。

4. 什么是SpanID

一個(gè)span代表在分布式系統(tǒng)中完成的單個(gè)工作單元,這個(gè)工作單元有唯一ID去標(biāo)識(shí),這個(gè)唯一ID就是Span ID。也包含其他span的“引用”,這允許將多個(gè)spans組合成一個(gè)完整的Trace。

通俗解釋就是在Trace這樣一個(gè)完整調(diào)用的流程中,Span扮演的角色就是每次執(zhí)行的一次IO或者非IO操作。所以你通過Trace找到整個(gè)鏈路,然后從鏈路中找到確定的Span,這樣就可以準(zhǔn)確定位一次問題或者性能查詢。

5. 其他名稱解釋

Span tags(跨度標(biāo)簽)可以理解為用戶自定義的Span注釋。便于查詢、過濾和理解跟蹤數(shù)據(jù)。

Span logs(跨度日志)可以記錄Span內(nèi)特定時(shí)間或事件的日志信息。主要用于捕獲特定Span的日志信息以及應(yīng)用程序本身的其他調(diào)試或信息輸出。

SpanContext 代表跨越進(jìn)程邊界,傳遞到子級(jí)Span的狀態(tài)。常在追蹤示意圖中創(chuàng)建上下文時(shí)使用。

6. 案例

-[]

圖中可以看到以下內(nèi)容:

  • 執(zhí)行時(shí)間的上下文
  • 服務(wù)間的層次關(guān)系
  • 服務(wù)間串行或并行調(diào)用鏈

結(jié)合以上信息,在實(shí)際場景中我們可以通過整個(gè)系統(tǒng)的調(diào)用鏈的上下文、性能等指標(biāo)信息,一下子就能夠發(fā)現(xiàn)系統(tǒng)的痛點(diǎn)在哪兒。

7. 什么是ZipKin

Zipkin是分布式追蹤系統(tǒng)。它的作用是收集解決微服務(wù)架構(gòu)中的延遲問題所需的時(shí)序數(shù)據(jù)。它管理這些數(shù)據(jù)的收集和查找。

Zipkin的設(shè)計(jì)基于Google Dapper論文。

8. 基于ZipKin構(gòu)建鏈路追蹤

首先在基于之前的項(xiàng)目之中,把server.go修改一下,讓其支持分布式鏈路追蹤。server.go:

<pre data-tool="mdnice編輯器" style="box-sizing: border-box !important; margin: 10px 0px; padding: 0px; outline: 0px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 14px; overflow: auto; display: block; color: rgb(33, 37, 41); max-width: 100%; overflow-wrap: break-word !important; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.8px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0.8px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`const (
SERVICE_NAME = "simple_zipkin_server"
ZIPKIN_HTTP_ENDPOINT = "http://127.0.0.1:9411/api/v2/spans" //上報(bào)到ZipKin中的鏈路
ZIPKIN_RECORDER_HOST_PORT = "0.0.0.0"
)

func main() {
...

//鏈路日志輸出到哪
reporter := httpreporter.NewReporter(ZIPKIN_HTTP_ENDPOINT)
defer reporter.Close()

//記錄服務(wù)名稱和端口
endpoint, err := zipkin.NewEndpoint(SERVICE_NAME, ZIPKIN_RECORDER_HOST_PORT)
if err != nil {
log.Fatalf("zipkin.NewEndpoint err: %v", err)
}

tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
if err != nil {
log.Fatalf("zipkin.NewTracer err: %v", err)
}

//接入opentracing
t := zipkinot.Wrap(tracer)
opentracing.SetGlobalTracer(t)

logrus.Infof("starting hello service at: %s", *port)

//初始化grpc server,并注冊(cè)中間件
s := grpc.NewServer(
// otgrpc.LogPayloads 是否記錄 入?yún)⒑统鰠?br> // otgrpc.SpanDecorator 裝飾器,回調(diào)函數(shù)
// otgrpc.IncludingSpans 是否記錄
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(otgrpc.OpenTracingServerInterceptor(t,
otgrpc.LogPayloads(),
// IncludingSpans是請(qǐng)求前回調(diào)
otgrpc.IncludingSpans(func(parentSpanCtx opentracing.SpanContext, method string, req, resp interface{}) bool {
log.Printf("method: %s", method)
log.Printf("req: %+v", req)
log.Printf("resp: %+v", resp)
return true
}),
// SpanDecorator是請(qǐng)求后回調(diào)
otgrpc.SpanDecorator(func(span opentracing.Span, method string, req, resp interface{}, grpcError error) {
log.Printf("method: %s", method)
log.Printf("req: %+v", req)
log.Printf("resp: %+v", resp)
log.Printf("grpcError: %+v", grpcError)
}),
))),
)

//注冊(cè)服務(wù)
pb.RegisterGreeterServer(s, &server{})
fmt.Println("ddd")
s.Serve(lis)
}` </pre>

至此我們的grpc服務(wù)就有了鏈路追蹤功能,接下來我們演示下,啟動(dòng)server.go:k8s-grpc-demo go run cmd/svr/svr.go -port 50004

然后啟動(dòng)客戶端:k8s-grpc-demo go run cmd/cli/cli.go

我們可以看下server.go的日志:
圖片

我們發(fā)現(xiàn)日志完美記錄到ZipKin中,接下來我們看下ZipKin地址:
圖片

當(dāng)我們點(diǎn)擊RUN QUERY的時(shí)候可以看到如下:
圖片

當(dāng)我們點(diǎn)擊某一個(gè)Trace的時(shí)候,就進(jìn)入這個(gè)Trace的整個(gè)調(diào)用鏈路詳情中:

圖片

這樣我就基于gRPC + Opentracing + Zipkin的分布式鏈路追蹤系統(tǒng)就搭建完成了,大家下去可以自己嘗試下。

9. 小結(jié)

各位讀者朋友們,我們的Go微服務(wù)架構(gòu)實(shí)戰(zhàn)【上中下】系列課程到這里就基本上結(jié)束了,寫作過程中雖然很累,很艱辛,但是這個(gè)系列能在有限的業(yè)余時(shí)間堅(jiān)持創(chuàng)作完實(shí)屬不易,希望在之后的業(yè)余時(shí)間當(dāng)中能繼續(xù)為大家?guī)砀舻南盗姓n程,歡迎大家點(diǎn)贊、關(guān)注和分享。

最后再次感謝大家對(duì)本系列課程的大力支持,由于個(gè)人能力有限,難免哪里寫的有問題歡迎大家指出,也歡迎各位能在百忙之中抽出時(shí)間學(xué)習(xí),最后和各位分享一句話:簡單的東西不一定是最好的,但最好的東西一定是簡單的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容