Spring Cloud Alibaba(13)---Sleuth概述

雨點的名字發表於2021-06-06

Sleuth概述

前言

在微服務架構中,眾多的微服務之間互相呼叫,如何清晰地記錄服務的呼叫鏈路是一個需要解決的問題。同時,由於各種原因,跨程式的服務呼叫失敗時,運維人員希望能夠通過

檢視日誌和檢視服務之間的呼叫關係來定位問題,而Spring cloud sleuth元件正是為了解決微服務跟蹤的元件。

一、背景

1、微服務的現狀?

隨著微服務架構的流行,服務按照不同的維度進行拆分,一次請求往往需要涉及到多個服務。在複雜的微服務架構系統中,幾乎每一個前端請求都會形成一個複雜的分散式服務呼叫

鏈路。一個請求完整呼叫鏈可能如下圖所示(盜圖):

Spring Cloud Alibaba(13)---Sleuth概述

隨著業務規模不斷增大、服務不斷增多以及頻繁變更的情況下,面對複雜的呼叫鏈路就帶來一系列問題:

如何快速發現問題?
如何判斷故障影響範圍?
如何梳理服務依賴以及依賴的合理性?
如何分析鏈路效能問題以及實時容量規劃?

 
而鏈路追蹤的出現正是為了解決這種問題,它可以在複雜的服務呼叫中定位問題,除此之外,如果某個介面突然耗時增加,也不必再逐個服務查詢耗時情況,我們可以直觀地分析

出服務的效能瓶頸,方便在流量激增的情況下精準合理地擴容。

2、什麼是鏈路追蹤

單純的理解鏈路追蹤,就是將一次分散式請求還原成呼叫鏈路,進行日誌記錄,效能監控並將一次分散式請求的呼叫情況集中展示。比如各個服務節點上的耗時、請求具體到

達哪臺機器上、每個服務節點的請求狀態等等。

3、鏈路追蹤相關產品

常見的鏈路追蹤技術有下面這些:

cat:由大眾點評開源,基於Java開發的實時應用監控平臺,包括實時應用監控,業務監控 。 整合方案是通過程式碼埋點的方式來實現監控,比如: 攔截器,過濾器等。 對程式碼

的侵入性很大,整合成本較高。風險較大。

zipkin:由Twitter公司開源,開放原始碼分散式的跟蹤系統,用於收集服務的定時資料,以解決微服務架構中的延遲問題,包括:資料的收集、儲存、查詢和展現。該產品結合

spring-cloud-sleuth使用較為簡單, 整合很方便, 但是功能較簡單。

pinpoint:Pinpoint是韓國人開源的基於位元組碼注入的呼叫鏈分析,以及應用監控分析工具。特點是支援多種外掛, UI功能強大,接入端無程式碼侵入。

skywalking:本土開源的基於位元組碼注入的呼叫鏈分析,以及應用監控分析工具。特點是支援多種外掛, UI功能較強,接入端無程式碼侵入。目前已加入Apache孵化器。

Sleuth:SpringCloud 提供的分散式系統中鏈路追蹤解決方案。

注意: SpringCloud alibaba技術棧中並沒有提供自己的鏈路追蹤技術的,我們可以採用Sleuth +Zinkin來做鏈路追蹤解決方案


二、Sleuth概述

1、什麼是Sleuth

Spring Cloud Sleuth 為 Spring Cloud 實現了分散式跟蹤解決方案。相容 Zipkin,HTrace 和其他基於日誌的追蹤系統,例如 ELK(Elasticsearch 、Logstash、 Kibana)。

Spring Cloud Sleuth 提供了以下功能:

鏈路追蹤:通過 Sleuth 可以很清楚的看出一個請求都經過了那些服務,可以很方便的理清服務間的呼叫關係等。

效能分析:通過 Sleuth 可以很方便的看出每個取樣請求的耗時,分析哪些服務呼叫耗時,當服務呼叫的耗時隨著請求量的增大而增大時, 可以對服務的擴容提供一定的提醒。

資料分析,優化鏈路:對於頻繁呼叫一個服務,或並行呼叫等,可以針對業務做一些優化措施。

視覺化錯誤:對於程式未捕獲的異常,可以配合 Zipkin 檢視。

2、Sleuth基本概念

Sleuth基本概念涉及到三個專業術語: spanTraceAnnotations

span

基本工作單位,每次傳送一個遠端呼叫服務就會產生一個 Span。Span 是一個 64 位的唯一 ID。通過計算 Span 的開始和結束時間,就可以統計每個服務呼叫所花費的時間。。

Trace

一系列 Span 組成的樹狀結構,一個 Trace 認為是一次完整的鏈路,內部包含 n 多個 Span。Trace 和 Span 存在一對多的關係,Span 與 Span 之間存在父子關係。

Annotations

用來及時記錄一個事件的存在,一些核心 annotations 用來定義一個請求的開始和結束。

cs - Client Sent:客戶端發起一個請求,這個 annotation 描述了這個 span 的開始;
sr - Server Received:服務端獲得請求並準備開始處理它,如果 sr 減去 cs 時間戳便可得到網路延遲;
ss - Server Sent:請求處理完成(當請求返回客戶端),如果 ss 減去 sr 時間戳便可得到服務端處理請求需要的時間;
cr - Client Received:表示 span 結束,客戶端成功接收到服務端的回覆,如果 cr 減去 cs 時間戳便可得到客戶端從服務端獲取回覆的所有所需時間。

核心 為什麼能夠進行整條鏈路的追蹤? 其實就是一個 Trace ID 將 一連串的 Span 資訊連起來了。根據 Span 記錄的資訊再進行整合就可以獲取整條鏈路的資訊。

3、舉例理解Sleuth基本概念

上面這樣寫可能有點抽象,這裡通過實際例子來解釋(盜圖)

Spring Cloud Alibaba(13)---Sleuth概述

1)這個圖中 從1->6 是一個完整的請求,所以這個完整的請求中有一個相同的TraceId。

2)server1->server2 可以理解是一個介面的請求,所以他們有著相同的SpanId。同樣道理 server2->server3,server2->server4 也有著相同的SpanId。同時parentid,

就是上一級的SpanId。

3)server1中的 cs cr - 分別代表請求server2的開始時間,和server1接收響應時間。(cr – cs)時間戳便可以得到整個請求所消耗的時間

4)server2中的 sr ss - 分別代表server2獲取請求並準備開始處理它的開始時間,ss (服務端傳送響應)– 代表server2服務結束執行時間。


二、實現原理

這裡通過圖片來循序漸進的理解Sleuth基本概念

如果想知道一個介面在哪個環節出現了問題,就必須清楚該介面呼叫了哪些服務,以及呼叫的順序,如果把這些服務串起來,看起來就像鏈條一樣,我們稱其為呼叫鏈。

Spring Cloud Alibaba(13)---Sleuth概述

想要實現呼叫鏈,就要為每次呼叫做個標識,然後將服務按標識大小排列,可以更清晰地看出呼叫順序,我們暫且將該標識命名為 spanid。

Spring Cloud Alibaba(13)---Sleuth概述

實際場景中,我們需要知道某次請求呼叫的情況,所以只有 spanid 還不夠,得為每次請求做個唯一標識,這樣才能根據標識查出本次請求呼叫的所有服務,而這個標識我們命名

為 traceid。

Spring Cloud Alibaba(13)---Sleuth概述

現在根據 spanid 可以輕易地知道被呼叫服務的先後順序,但無法體現呼叫的層級關係,正如下圖所示,多個服務可能是逐級呼叫的鏈條,也可能是同時被同一個服務呼叫。

Spring Cloud Alibaba(13)---Sleuth概述

所以應該每次都記錄下是誰呼叫的,我們用 parentid 作為這個標識的名字。

Spring Cloud Alibaba(13)---Sleuth概述

到現在,已經知道呼叫順序和層級關係了,但是介面出現問題後,還是不能找到出問題的環節,如果某個服務有問題,那個被呼叫執行的服務一定耗時很長,要想計算出耗時,

上述的三個標識還不夠,還需要加上時間戳,時間戳可以更精細一點,精確到微秒級。

Spring Cloud Alibaba(13)---Sleuth概述

只記錄發起呼叫時的時間戳還算不出耗時,要記錄下服務返回時的時間戳,有始有終才能算出時間差,既然返回的也記了,就把上述的三個標識都記一下吧,不然區分不出是

誰的時間戳。

Spring Cloud Alibaba(13)---Sleuth概述

雖然能計算出從服務呼叫到服務返回的總耗時,但是這個時間包含了服務的執行時間和網路延遲,有時候我們需要區分出這兩類時間以方便做針對性優化。那如何計算網路延遲

呢?我們可以把呼叫和返回的過程分為以下四個事件。

Client Sent 簡稱 cs,客戶端發起呼叫請求到服務端。
Server Received 簡稱 sr,指服務端接收到了客戶端的呼叫請求。
Server Sent 簡稱 ss,指服務端完成了處理,準備將資訊返給客戶端。
Client Received 簡稱 cr,指客戶端接收到了服務端的返回資訊。

Spring Cloud Alibaba(13)---Sleuth概述

假如在這四個事件發生時記錄下時間戳,就可以輕鬆計算出耗時,比如 `sr 減去 cs 就是呼叫時的網路延遲,ss 減去 sr 就是服務執行時間,cr 減去 ss 就是服務響應的延遲,

cr 減 cs 就是整個服務呼叫執行的時間`。

Spring Cloud Alibaba(13)---Sleuth概述

其實 span 內除了記錄這幾個引數之外,還可以記錄一些其他資訊,比如發起呼叫服務名稱、被調服務名稱、返回結果、IP、呼叫服務的名稱等,最後,我們再把相同 parentid

的 span 資訊合成一個大的 span 塊,就完成了一個完整的呼叫鏈。


參考

Spring Cloud 系列之 Sleuth 鏈路追蹤(一)

我把「鏈路追蹤」整明白了



少說多做,句句都會得到別人的重視;多說少做,句句都會受到別人的忽視。(13)

相關文章