Dapr提供了一些開箱即用的分布式鏈路追蹤解決方案,今天我們來講一講如何通過dapr的configuration來實現非侵入式鏈路追蹤的
目錄:
一、通過Dapr實現一個簡單的基於.net的微服務電商系統
二、通過Dapr實現一個簡單的基於.net的微服務電商系統(二)——通訊框架講解
三、通過Dapr實現一個簡單的基於.net的微服務電商系統(三)——一步一步教你如何擼Dapr
四、通過Dapr實現一個簡單的基於.net的微服務電商系統(四)——一步一步教你如何擼Dapr之訂閱發布
五、通過Dapr實現一個簡單的基於.net的微服務電商系統(五)——一步一步教你如何擼Dapr之狀態管理
六、通過Dapr實現一個簡單的基於.net的微服務電商系統(六)——一步一步教你如何擼Dapr之Actor服務
七、通過Dapr實現一個簡單的基於.net的微服務電商系統(七)——一步一步教你如何擼Dapr之服務限流
八、通過Dapr實現一個簡單的基於.net的微服務電商系統(八)——一步一步教你如何擼Dapr之鏈路追蹤
九、通過Dapr實現一個簡單的基於.net的微服務電商系統(九)——一步一步教你如何擼Dapr之OAuth2授權 && 百度版Oauth2
十、通過Dapr實現一個簡單的基於.net的微服務電商系統(十)——一步一步教你如何擼Dapr之綁定
十一、通過Dapr實現一個簡單的基於.net的微服務電商系統(十一)——一步一步教你如何擼Dapr之自動擴/縮容
十二、通過Dapr實現一個簡單的基於.net的微服務電商系統(十二)——istio+dapr構建多運行時服務網格
十三、通過Dapr實現一個簡單的基於.net的微服務電商系統(十三)——istio+dapr構建多運行時服務網格之生產環境部署
十四、通過Dapr實現一個簡單的基於.net的微服務電商系統(十四)——開發環境容器調試小技巧
十五、通過Dapr實現一個簡單的基於.net的微服務電商系統(十五)——集中式接口文檔實現
十六、通過Dapr實現一個簡單的基於.net的微服務電商系統(十六)——dapr+sentinel中間件實現服務保護
十七、通過Dapr實現一個簡單的基於.net的微服務電商系統(十七)——服務保護之動態配置與熱重載
附錄:(如果你覺得對你有用,請給個star)
一、電商Demo地址
首先依然簡單聊聊什么是鏈路追蹤以及我們為什么需要它,知道鏈路追蹤的同學可以跳過。在傳統的單體應用中,我們的每一次請求往往在同一個進程中被一次性處理。而在分布式系統中,我們需要通過不同容器隔離甚至物理機隔離的服務間協同作業來實現某些業務,同時由於業務流轉會涉及到接口調用、事件訂閱、狀態讀寫、actor調用等等情況,往往想要追蹤它們形成一個鏈式調用的記錄會比較困難。這里舉一個例子,某分布式系統集群運行在生產環境上,某日收到預警某接口調用非常緩慢。這個時候開發人員排查發現該聚合網關接口調用了服務A、B、C但是不知道具體是哪個服務導致的緩慢,通知A、B、C對應的開發組人員通過本地調試發現A、B、調用正常,C緩慢,但是C發現並非由於自身業務邏輯緩慢,而是自己調用D時返回比較緩慢,這時又只得通知D負責的團隊進行業務排查,最終D發現自己的代碼問題,然后逐一修復並發布到生產環境解決該問題。這個例子比較極端哈,這里僅舉個例子說明。鏈路追蹤系統就是幫助分布式系統在鏈路調用時記錄每一個接口的響應時間以及自己依賴的下游接口的響應時間並提供可視化UI方便開發運維團隊快速排查接口調用耗時異常定位問題。
傳統的鏈路追蹤一般是通過代碼侵入式的方式由開發人員集成SDK插入代理,應用上線運行后這些代理即可自動化監視我們的應用進程記錄流量流入、流出請求/響應時間並統一上報到鏈路追蹤系統,而service mesh由於sidecar的存在可以確保流量在流入/流出應用時一定會經過sidecar,所以天生更容易實現鏈路追蹤,從而免於讓開發人員人工通過SDK的方式去集成一個分布式鏈路追蹤系統,接下來就講講我們在dapr下如何來實現它。
首先我們需要在k8s環境跑起來一個鏈路追蹤系統,大家可以看看這里是目前dapr支持的鏈路后端,我這里就選型我比較熟悉的zipkin來實現。zip在k8s中很容易跑起來,這是yaml:
--- apiVersion: apps/v1 kind: Deployment metadata: name: zipkin spec: selector: matchLabels: app: zipkin replicas: 1 template: metadata: labels: app: zipkin spec: containers: - name: zipkin image: openzipkin/zipkin:latest imagePullPolicy: IfNotPresent ports: - containerPort: 9411 env: - name: TZ value: "Asia/Shanghai" --- apiVersion: v1 kind: Service metadata: name: zipkin spec: type: NodePort selector: app: zipkin ports: - protocol: TCP port: 9411 targetPort: 9411
由於需要在本地訪問zip的website,我這里偷懶直接將nodeport暴露到本地k8s集群,方便等會兒通過瀏覽器訪問。現在我們apply一下,稍微等待一段時間k8s拉取鏡像並運行起來后,通過kubectl get svc 查詢zipkin暴露的隨機端口即可通過localhost:nodeport訪問到zipkin的界面:
接下來就比較簡單了,我們創建一個類型為configuration的配置文件,並注入到每一個需要追蹤的服務即可,其中samplingRate是指采樣率,而endpointAddress是指我們在k8s集群內通過svc能訪問到的zipkin的地址(如果你的zipkin部署在非本集群,則可通過ip or 網址的方式訪問):
apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: zipkin spec: metric: enabled: true tracing: samplingRate: "1" zipkin: endpointAddress: "http://zipkin.infrastructure.svc.cluster.local:9411/api/v2/spans"
接着我們將這個configuration注入到我們需要的服務中,這里我們直接看電商demo yaml文件賬戶服務的情況(紅字部分):
apiVersion: apps/v1 kind: Deployment metadata: name: accountservice namespace: dapreshop labels: app: accountservice spec: replicas: 1 selector: matchLabels: app: accountservice minReadySeconds: 5 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: accountservice version: v1 annotations: dapr.io/enabled: "true" dapr.io/app-id: "accountservice" dapr.io/app-port: "80" dapr.io/config: "zipkin" spec: containers: - name: web image: accountservice:release imagePullPolicy: Never readinessProbe: httpGet: path: v1.0/healthz port: 3500 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds : 5 failureThreshold : 3 ports: - containerPort: 80
現在我們來下單看看,訪問admin.dapreshop.com:30882,初始化系統后,訪問m.dapreshop.com:30882,下單一次。接着打開我們的zipkin,查詢run query即可看到最新一條鏈路追蹤記錄如下:
可以看到鏈路追蹤的root是我們的apigateway,因為客戶端請求是從這里被聚合的。接着apigateway會調用商品服務、交易服務、用戶服務、以及作業系統。這里我們再看看我們的代碼看看createorder明細:
這個用例服務會調用用戶服務獲取一個mockaccount模擬用戶用於下單,接着會調用一個創建訂單的領域服務用於下單這里會調用商品的actor服務用於原子減扣庫存(此部分可參考之前的actor文章),下單完成后會發送一個訂單創建成功事件,由作業系統訂閱並等待5分鍾后進行未支付訂單取消操作,整個下單流程如下:
整個流程相對比較簡單,通過在daprd sidecar上申明了zipkin configuration后 daprd會忠實的將我們的請求轉化為鏈路追蹤記錄並上報zipkin,我們點開zipkin那條記錄查看明細如下:
可以非常清楚的看到我們的訂單創建調用的賬戶服務的mockaccount接口,然后調用了商品服務的商品信息接口,接着調用數個商品actor進行庫存減扣,最終持久化我們的訂單后發起一個事件並且成功的被作業系統訂閱。每一個接口請求了多少時間被清楚的記錄了下來,這樣在生產環境下就很容易排除慢接口的問題而不用像上面提到的那樣各個團隊忙的焦頭爛額了
dapr目前還提供了其他的一些鏈路追蹤客戶端,但是整體大的流程基本如本文所述,今天的分享就到這里,希望大家多多支持dapr,多多轉發fork+star。下一次我們將分享一下如何集成一個第三方的oauth授權服務來實現oauth。