
本篇文章我將給大家介紹“分布式鏈路追蹤”的內容,對于目前大部分采用微服務架構的公司來說,分布式鏈路追蹤都是必備的,無論它是傳統微服務體系亦或是新一代Service Mesh的微服務架構!而具體介紹的內容,本文不是完全講理論,而是希望從理論到實踐,引導大家去操作,因為只有這樣才能真正從技術層面有深刻的認識和了解!
分布式鏈路追蹤概述
在具體介紹分布式鏈路追蹤系統之前,我們首先需要理解下什么是鏈路追蹤?在本專欄前面關于監控系統的介紹中可以知道,監控系統的觀測資料主要來源于統計指標、日志以及鏈路追蹤這三個方面,而這些資料從型別上又可以劃分為兩種:請求級別、聚合級別,
請求級別的資料主要來源于真實的請求,例如一次HTTP呼叫、RPC呼叫等,本文要介紹的鏈路追蹤就是這種型別,而聚合級別則是介面請求的度量指標或者一些引數資料的聚合,如QPS、CPU使用率等數值,日志和統計指標資料既可以是請求級別,也可以是聚合級別,因為它們可能來自源于真實的請求,也可能是系統自身診斷時記錄下來的資訊,
而對于鏈路追蹤來說,它主要的邏輯就是將請求鏈路的完整行為記錄下來,以便可以通過可視化的形式實作鏈路查詢、性能分析、依賴關系、拓撲圖等分布式鏈路追蹤相關的功能,如下圖所示:
在上圖中假設微服務系統中的一次介面呼叫總共有兩個微服務參與,其呼叫關系分別是A->B->C,其中B服務還與Redis這樣的第三方服務產生了呼叫關系、C服務則還需要呼叫MySQL資料庫服務,所以實際上鏈路追蹤所做的事情就是詳細記錄A->B(B->Redis)->C(C->MySQL)這條完整鏈路上的詳細呼叫資訊,例如介面回應結果、耗時等,
那么這條呼叫鏈路上的資料到底是怎樣被記錄的呢?接下來我們繼續以上面的呼叫鏈為例分析下鏈路追蹤資訊的具體組成和傳遞形式,以便進一步理解分布式鏈路追蹤系統的原理和概念,具體邏輯示意圖如下:
如上圖所示,分布式鏈路追蹤所監控的物件就是一次次呼叫所產生的鏈路,圖中1-8所示的就是一條完整的鏈路(Trace),系統會通過唯一的標識(TraceId)對此進行記錄,而鏈路中的每一個依賴呼叫都會生成一個呼叫蹤跡資訊(Span),最開始生成的Span叫做根Span(Root Span),后續生成的Span都會將前一個Span 的標示(Sid)作為本Span資訊的父ID(Pid),
這樣以此類推,Span資訊就會隨著鏈路的執行被行程內或跨行程進行背景關系傳遞,通過Span資料鏈就能將一次次鏈路呼叫所產生的蹤跡資訊串聯起來,而每一個Span之上附著的日志資訊(Annotation)就是我們進行呼叫鏈監控分析的資料來源,這就是分布式鏈路追蹤的基本原理,
而說到這里,你可能會有疑問:監控這么大的資料量,是不是會很消耗系統資源?的確如此,所以大部分鏈路追蹤系統,都會存在一個叫做采樣率(Sampling)的設定,用來控制系統采集鏈路資訊的比例,從而提升系統性能,因為很多時候,大量的鏈路資訊都是相同的,我們需要關注的可能也只是相對耗時較高、出錯次數較多的鏈路,而并沒有必要100%的進行采集,
SkyWalking簡介
前面我們從基本原理的角度說明了鏈路追蹤是什么,那么接下來我們將介紹下目前最流行的分布式鏈路追蹤系統——SkyWalking,
SkyWalking是一款優秀的開源APM(Application Performance Management)系統,它不僅提供了鏈路追蹤,鏈路分析等分布式追蹤功能,還支持性能指標分析、應用和服務依賴性分析、服務拓撲圖分析、報警等一系列應用性能監控相關的功能,可以幫助我們有效地定位問題,
而從資料收集上看,SkyWalking支持多種不同的資料來源及格式,包括支持Java、.NET Core、NodeJS、PHP和Python等不同語言的無侵入式Agent探針,以及對Service Mesh(服務網格)架構的支持等,其具體結構如下圖所示:
如上圖所示,SkyWalking的核心由鏈路收集服務器(Receiver Cluster)、聚合服務器(AggregatorCluster)組成,其中Receiver Cluster是整個后端服務接入的入口,專門用于收集服務的各種指標及鏈路資訊,
而AggregatorCluster則用于匯總、聚合收集器收集到的資料,并最終將聚合資料存盤到資料庫中,而具體存盤方式可以有多種,例如常見的ElasticSearch、MySQL、TIDB等,我們可以根據實際需要進行選擇,這些聚合資料后面可以用于告警設定,也可以被GUI/CLI等可視化系統以HTTP的形式訪問后進行可視化展示,
此外,從資料采集邏輯上看,SkyWalking支持多種語言探針及專案協議,能夠覆寫目前大部分主流的分布式技術堆疊,具體來說主要有以下3種:
-
Metrics System:統計系統,支持直接從Prometheus中拉取度量指標資料到SkyWalking,也支持程式自身通過micrometer推送資料;
-
Agents:業務探針,指在各個業務系統中集成探針服務來進行鏈路追蹤,即鏈路資料采集,SkyWalking支持Java、Go、.NET、PHP、NodeJS、Python、Nginx LUA等多種語言的探針,此外,它還支持通過gRPC或者HTTP的方式來傳遞資料;
-
Service Mesh:SkyWalking還支持對新一代微服務架構Service Mesh的監控,可以通過特定的Service Mesh協議采集資料面、控制面的資料,實作對服務網格鏈路資料的觀測;
上面的內容簡單介紹了SkyWalking的基本情況,并就其系統架構進行了簡單分析,實際上SkyWalking最近兩年發展得非常快,社區也非常活躍,在微服務鏈路追蹤、應用性能監控領域被使用得也越來越廣泛,由于篇幅原因,這里無法進行更深入的分享,感興趣的讀者可以通過官方檔案或社區進行深入了解!
SkyWalking安裝部署
前面的內容分別介紹了分布式鏈路追蹤的基本原理,并著重介紹了SkyWalking!很顯然,寫到這里就結束的話,本文就沒有啥價值了,因為只是說了一堆正確的廢話,看了也就忘了!這顯然也不符合我分享的風格,接下來我們就從實驗的角度來玩一下SkyWalking,
以下內容需要進行實際實驗操作,如果在地鐵上不方便可以先收藏,有時間再具體實驗玩下!
對于SkyWalking的部署主要涉及到后端OAP Server和前端UI,根據實際需要可以將它們部署在物理機、虛擬機或者Kubernetes集群之中,這里為了演示環境的一致性,我們選擇將SkyWalking的后端服務及UI分別部署到Kubernetes集群中,
而具體安裝SkyWalking的方式可以通過官方提供的Kubernetes部署檔案采用Helm方式安裝,也可以手動撰寫Kubernetes部署檔案,這里為了便于學習,我們采用后一種方式,具體步驟如下:
1)、在Kubernetes集群中創建一個單獨運行SkyWalking容器的Namespace,命令如下:
#通過kubectl連接Kubernetes集群后執行,創建namespace命令
$ kubectl create ns skywalking
命令執行完成后,可以查看Namespace是否創建成功,命令如下:
#查看namespace創建情況
$ kubectl get ns
NAME STATUS AGE
default Active 10d
kube-node-lease Active 10d
kube-public Active 10d
kube-system Active 10d
kubernetes-dashboard Active 10d
skywalking Active 46s
可以看到此時skywalking空間已經成功創建!
2)、撰寫SkyWalking-UI及OAP Server服務Kubernetes部署檔案
在撰寫具體的Kubernetes部署檔案的程序中需要指定SkyWalking-UI及OAP Server的容器鏡像,一般來說可以通過原始碼手動打包也可以直接使用官方已經打包好的鏡像,這里為了方便演示,采用Docker官方鏡像倉庫中已經打包好的鏡像,具體如圖所示:
如果上面兩張圖所示,我們分別在Docker Hub官方鏡像倉庫中找到了SkyWalking-UI及OAP Server的官方發布的容器鏡像版本,接下來撰寫具體的部署檔案,
撰寫SkyWalking服務端Kubernetes部署檔案(skywalking-aop.yml),具體內容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: oap
namespace: skywalking
spec:
replicas: 1
selector:
matchLabels:
app: oap
release: skywalking
template:
metadata:
labels:
app: oap
release: skywalking
spec:
containers:
- name: oap
#指定OAP Server容器鏡像及版本資訊
image: apache/skywalking-oap-server:8.3.0-es7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 11800
name: grpc
- containerPort: 12800
name: rest
---
apiVersion: v1
kind: Service
metadata:
name: oap
namespace: skywalking
labels:
service: oap
spec:
ports:
#restful埠
- port: 12800
name: rest
#rpc埠
- port: 11800
name: grpc
- port: 1234
name: page
selector:
app: oap
以上是一個標準的Kubernetes部署檔案,關于檔案中相關指令的具體含義可查閱Kubernetes相關的資料,
撰寫SkyWalking-UI部署檔案(skywalking-ui.yml),具體內容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui-deployment
namespace: skywalking
labels:
app: ui
spec:
replicas: 1
selector:
matchLabels:
app: ui
template:
metadata:
labels:
app: ui
spec:
containers:
- name: ui
image: apache/skywalking-ui:8.3.0
ports:
- containerPort: 8080
name: page
env:
- name: SW_OAP_ADDRESS
value: oap:12800
---
apiVersion: v1
kind: Service
metadata:
name: ui
namespace: skywalking
labels:
service: ui
spec:
ports:
- port: 8080
name: page
nodePort: 31234
type: NodePort
selector:
app: ui
3)、根據撰寫的部署檔案,執行Kubernetes部署命令
根據前面步驟中撰寫的Kubernetes發布檔案,這里我們根據撰寫的發布檔案直接執行部署命令,具體如下:
#進入發布檔案的存盤目錄,直接一次性執行全部檔案部署命令
$ kubectl apply -f .
deployment.apps/oap created
service/oap created
deployment.apps/ui-deployment created
service/ui created
執行完成后通過命令查看具體部署的情況,命令如下:
#查看skywalking空間中的Pod、Service物件的運行情況
$ kubectl get all -n skywalking
NAME READY STATUS RESTARTS AGE
pod/oap-5f6d6bc4f6-k4mvv 1/1 Running 0 36h
pod/ui-deployment-868c66449d-fffrt 1/1 Running 0 36h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/oap ClusterIP 10.110.112.244 <none> 12800/TCP,11800/TCP,1234/TCP 36h
service/ui NodePort 10.100.154.93 <none> 8080:31234/TCP 36h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/oap 1/1 1 1 36h
deployment.apps/ui-deployment 1/1 1 1 36h
NAME DESIRED CURRENT READY AGE
replicaset.apps/oap-5f6d6bc4f6 1 1 1 36h
replicaset.apps/ui-deployment-868c66449d 1 1 1 36h
可以看到部署的SkyWalking服務都已經正常運行!如果是第一次部署,拉取鏡像的程序可能會比較慢一點,如果在部署程序中存在問題,也可以查看Pod物件的運行日志,例如:
#可以查看aop的啟動日志
$ kubectl logs pod/oap-5f6d6bc4f6-k4mvv -n skywalking
4)、查看SkyWalking-UI的Web訪問地址
經過上述步驟,我們已經成功將SkyWalking-UI、OAP Server兩個服務運行在Kubernetes集群之中,接下來通過SkyWalking-UI服務的映射埠(k8s部署檔案中定義是31234埠)訪問Web UI,具體可通過http://NodeIP:31234進行訪問,例如:
#這里的IP為Kubernetes集群向外暴露的節點入口IP
http://10.211.55.12:31234/
如果不知道Kubernetes集群節點入口IP地址,可以通過以下命令進行查看:
#查詢SkyWalking-UI所部署的Kubernetes集群Node節點的IP地址
$ kubectl describe node kubernetes
Name: kubernetes
Roles: master
...
Addresses:
InternalIP: 10.211.55.12
Hostname: kubernetes
...
訪問后的界面顯示效果如下圖所示:
如上圖所示,此時可以看到SkyWalking已成功運行,由于尚無服務接入所以暫時還看不到有任何監控資料!
后記
如前面所述內容我們已經在Kubernetes環境中將分布式鏈路追蹤系統部署成功了,另外由于還沒有服務接入所以暫時還看不到任何鏈路追蹤資料,但是由于篇幅的原因這里就不繼續介紹如何將Java微服務接入SkyWalking了,但是這個這個接入程序卻是非常有意思的,因為它是我們作為研發人員,進一步理解微服務程式與分布式鏈路追蹤系統集成、互動的關鍵!這部分我將作為續集在下一篇文章中給大家分享,時間不會太久,期待大家保持關注!
寫在最后
歡迎大家關注我的公眾號【風平浪靜如碼】,海量Java相關文章,學習資料都會在里面更新,整理的資料也會放在里面,
覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/267281.html
標籤:Java
上一篇:設計模式之單例模式(Singleton Pattern)
下一篇:Mybatis的CRUD
