Go微服務架構實戰 下篇:1. gRPC + Opentracing + Zipkin實現分散式鏈路追蹤系統
Go微服務架構實戰-【公粽號:堆疊future】
1. 微服務架構上篇
1. grpc技術介紹
2. grpc+protobuf+閘道器實戰
3. etcd技術介紹
4. 基於etcd的服務發現與註冊
5. 基於etcd的分散式鎖實戰
2. 微服務架構中篇
3. 微服務架構下篇
分散式鏈路追蹤實戰
乾貨:
什麼是APM
什麼是Opentracing
什麼是SpanID
什麼是TraceID
基於zipkin構建鏈路追蹤
1. 什麼是APM
APM
(Application Performance Management,即應用效能管理,在分散式領域也稱為分散式跟蹤管理)對企業的應用系統進行實時監控,它是用於實現對應用程式效能管理和故障管理的系統化的解決方案。
APM
核心功能:
-
服務呼叫跟蹤
-
應用系統存活檢測
-
監控告警
開源APM
管理工具:
-
ZipKin
-
PinPoint
-
SkyWalking
-
Prometheus
我們這篇文章主要是講解APM
的核心功能之一:服務呼叫跟蹤
,用到的工具是ZipKin
,本來想用Prometheus
2. 什麼是Opentracing
OpenTracing
通過提供平臺無關、廠商無關的API,使得開發人員能夠方便的新增(或更換)追蹤系統的實現。
不過OpenTracing並不是標準。因為CNCF不是官方標準機構,但是它的目標是致力為分散式追蹤建立更標準的API和工具。
3. 什麼是TraceID
一個trace
代表了一個事務或者流程在(分散式)系統中的執行過程,而這個過程會有唯一ID去標識,這個唯一ID就是Trace ID
,通俗解釋就是一個API請求的完整呼叫流程。
4. 什麼是SpanID
一個span
代表在分散式系統中完成的單個工作單元,這個工作單元有唯一ID去標識,這個唯一ID就是Span ID
通俗解釋就是在Trace這樣一個完整呼叫的流程中,Span扮演的角色就是每次執行的一次IO或者非IO操作。所以你通過Trace找到整個鏈路,然後從鏈路中找到確定的Span,這樣就可以準確定位一次問題或者效能查詢。
5. 其他名稱解釋
Span tags
(跨度標籤)可以理解為使用者自定義的Span註釋。便於查詢、過濾和理解跟蹤資料。
Span logs
(跨度日誌)可以記錄Span內特定時間或事件的日誌資訊。主要用於捕獲特定Span的日誌資訊以及應用程式本身的其他除錯或資訊輸出。
SpanContext
代表跨越程序邊界,傳遞到子級Span的狀態。常在追蹤示意圖中建立上下文時使用。
6. 案例
圖中可以看到以下內容:
-
執行時間的上下文
-
服務間的層次關係
-
服務間序列或並行呼叫鏈
結合以上資訊,在實際場景中我們可以通過整個系統的呼叫鏈的上下文、效能等指標資訊,一下子就能夠發現系統的痛點在哪兒。
7. 什麼是ZipKin
Zipkin
是分散式追蹤系統。它的作用是收集解決微服務架構中的延遲問題所需的時序資料。它管理這些資料的收集和查詢。
Zipkin的設計基於Google Dapper
論文。
8. 基於ZipKin構建鏈路追蹤
首先在基於之前的專案之中,把server.go修改一下,讓其支援分散式鏈路追蹤。server.go:
const(
SERVICE_NAME="simple_zipkin_server"
ZIPKIN_HTTP_ENDPOINT="http://127.0.0.1:9411/api/v2/spans"//上報到ZipKin中的鏈路
ZIPKIN_RECORDER_HOST_PORT="0.0.0.0"
)
funcmain(){
...
//鏈路日誌輸出到哪
reporter:=httpreporter.NewReporter(ZIPKIN_HTTP_ENDPOINT)
deferreporter.Close()
//記錄服務名稱和埠
endpoint,err:=zipkin.NewEndpoint(SERVICE_NAME,ZIPKIN_RECORDER_HOST_PORT)
iferr!=nil{
log.Fatalf("zipkin.NewEndpointerr:%v",err)
}
tracer,err:=zipkin.NewTracer(reporter,zipkin.WithLocalEndpoint(endpoint))
iferr!=nil{
log.Fatalf("zipkin.NewTracererr:%v",err)
}
//接入opentracing
t:=zipkinot.Wrap(tracer)
opentracing.SetGlobalTracer(t)
logrus.Infof("startinghelloserviceat:%s",*port)
//初始化grpcserver,並註冊中介軟體
s:=grpc.NewServer(
//otgrpc.LogPayloads是否記錄入參和出參
//otgrpc.SpanDecorator裝飾器,回撥函式
//otgrpc.IncludingSpans是否記錄
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(otgrpc.OpenTracingServerInterceptor(t,
otgrpc.LogPayloads(),
//IncludingSpans是請求前回調
otgrpc.IncludingSpans(func(parentSpanCtxopentracing.SpanContext,methodstring,req,respinterface{})bool{
log.Printf("method:%s",method)
log.Printf("req:%+v",req)
log.Printf("resp:%+v",resp)
returntrue
}),
//SpanDecorator是請求後回撥
otgrpc.SpanDecorator(func(span opentracing.Span,methodstring,req,respinterface{},grpcErrorerror){
log.Printf("method:%s",method)
log.Printf("req:%+v",req)
log.Printf("resp:%+v",resp)
log.Printf("grpcError:%+v",grpcError)
}),
))),
)
//註冊服務
pb.RegisterGreeterServer(s,&server{})
fmt.Println("ddd")
s.Serve(lis)
}
至此我們的grpc服務就有了鏈路追蹤功能,接下來我們演示下,啟動server.go:k8s-grpc-demo go run cmd/svr/svr.go -port 50004
然後啟動客戶端:k8s-grpc-demo go run cmd/cli/cli.go
我們可以看下server.go的日誌:我們發現日誌完美記錄到ZipKin中,接下來我們看下ZipKin地址:當我們點選RUN QUERY的時候可以看到如下:當我們點選某一個Trace的時候,就進入這個Trace的整個呼叫鏈路詳情中:
這樣我就基於gRPC + Opentracing + Zipkin
的分散式鏈路追蹤系統就搭建完成了,大家下去可以自己嘗試下。
9. 小結
各位讀者朋友們,我們的Go微服務架構實戰
【上中下】系列課程到這裡就基本上結束了,寫作過程中雖然很累,很艱辛,但是這個系列能在有限的業餘時間堅持創作完實屬不易,希望在之後的業餘時間當中能繼續為大家帶來更棒的系列課程,歡迎大家點贊、關注和分享。
最後再次感謝大家對本系列課程的大力支援,由於個人能力有限,難免哪裡寫的有問題歡迎大家指出,也歡迎各位能在百忙之中抽出時間學習,最後和各位分享一句話:簡單的東西不一定是最好的,但最好的東西一定是簡單的。
公粽號:堆疊future
使很多處於迷茫階段的coder能從這裡找到光明,堆疊創世,功在當代,利在千秋