第6章 Sleuth--鏈路追蹤
第6章 Sleuth–鏈路追蹤
6.1 鏈路追蹤介紹
在大型系統的微服務化構建中,一個系統被拆分成了許多模組。這些模組負責不同的功能,組合成 系統,最終可以提供豐富的功能。在這種架構中,一次請求往往需要涉及到多個服務。網際網路應用構建 在不同的軟體模組集上,這些軟體模組,有可能是由不同的團隊開發、可能使用不同的程式語言來實 現、有可能布在了幾千臺伺服器,橫跨多個不同的資料中心,也就意味著這種架構形式也會存在一些問題:
- 如何快速發現問題?
- 如何判斷故障影響範圍?
- 如何梳理服務依賴以及依賴的合理性?
- 如何分析鏈路效能問題以及實時容量規劃?
分散式鏈路追蹤(Distributed Tracing),就是將一次分散式請求還原成呼叫鏈路,進行日誌記錄, 效能監控並將一次分散式請求的呼叫情況集中展示。比如各個服務節點上的耗時、請求具體到達哪 臺機器 上、每個服務節點的請求狀態等等。
常見的鏈路追蹤技術有下面這些:
- cat 由大眾點評開源,基於Java開發的實時應用監控平臺,包括實時應用監控,業務監控 。 整合 方案是通過程式碼埋點的方式來實現監控,比如: 攔截器,過濾器等。 對程式碼的侵入性很大,整合成 本較高。風險較大。
- zipkin 由Twitter公司開源,開放原始碼分散式的跟蹤系統,用於收集服務的定時資料,以解決微 服務架構中的延遲問題,包括:資料的收集、儲存、查詢和展現。該產品結合spring-cloud-sleuth 使用較為簡單, 整合很方便, 但是功能較簡單。
- pinpoint Pinpoint是韓國人開源的基於位元組碼注入的呼叫鏈分析,以及應用監控分析工具。特點 是支援多種外掛,UI功能強大,接入端無程式碼侵入。
- skywalking SkyWalking是本土開源的基於位元組碼注入的呼叫鏈分析,以及應用監控分析工具。特點是支援多 種外掛,UI功能較強,接入端無程式碼侵入。目前已加入Apache孵化器。
- Sleuth SpringCloud 提供的分散式系統中鏈路追蹤解決方案
注意:SpringCloud alibaba技術棧中並沒有提供自己的鏈路追蹤技術的,我們可以採用Sleuth + Zinkin來做鏈路追蹤解決方案
6.2 Sleuth入門
6.2.1 Sleuth介紹
SpringCloud Sleuth主要功能就是在分散式系統中提供追蹤解決方案。它大量借用了Google Dapper的設計, 先來了解一下Sleuth中的術語和相關概念。
- Trace 由一組TraceId相同的Span串聯形成一個樹狀結構。為了實現請求跟蹤,當請求到達分散式系統的 入口端點時,只需要服務跟蹤框架為該請求建立一個唯一的標識(即TraceId),同時在分散式系 統內部流轉的時候,框架始終保持傳遞該唯一值,直到整個請求的返回。那麼我們就可以使用該唯 一標識將所有的請求串聯起來,形成一條完整的請求鏈路。
- Span代表了一組基本的工作單元。為了統計各處理單元的延遲,當請求到達各個服務元件的時 候,也通過一個唯一標識(SpanId)來標記它的開始、具體過程和結束。通過SpanId的開始和結 束時間戳,就能統計該span的呼叫時間,除此之外,我們還可以獲取如事件的名稱。請求資訊等 後設資料。
- Annotation 用它記錄一段時間內的事件,內部使用的重要註釋:
cs(Client Send)客戶端發出請求,開始一個請求的生命
sr(Server Received)服務端接受到請求開始進行處理, sr-cs = 網路延遲(服務呼叫的時間)
ss(Server Send)服務端處理完畢準備傳送到客戶端,ss - sr = 伺服器上的請求處理時間cr (Client Reveived)客戶端接受到服務端的響應,請求結束。 cr - sr = 請求的總時間
6.2.2 Sleuth入門
微服務名稱, traceId, spanid,是否將鏈路的追蹤結果輸出到第三方平臺
[api-gateway,3977125f73391553,3977125f73391553,false]
[service-order,3977125f73391553,57547b5bf71f8242,false]
[service-product,3977125f73391553,449f5b3f3ef8d5c5,false]
接下來通過之前的專案案例整合Sleuth,完成入門案例的編寫。 修改父工程引入Sleuth依賴:
啟動微服務,呼叫之後,我們可以在控制檯觀察到sleuth的日誌輸出:
其中 5399d5cb061971bd 是TraceId, 5399d5cb061971bd 是SpanId,依次呼叫有一個全域性的 TraceId,將呼叫鏈路串起來。仔細分析每個微服務的日誌,不難看出請求的具體過程。
檢視日誌檔案並不是一個很好的方法,當微服務越來越多日誌檔案也會越來越多,通過Zipkin可以 將日誌聚合,並進行視覺化展示和全文檢索。
6.3 Zipkin的整合
6.3.1 ZipKin介紹
Zipkin 是 Twitter 的一個開源專案,它基於Google Dapper實現,它致力於收集服務的定時資料, 以解決微服務架構中的延遲問題,包括資料的收集、儲存、查詢和展現。
我們可以使用它來收集各個伺服器上請求鏈路的跟蹤資料,並通過它提供的REST API介面來輔助我 們查詢跟蹤資料以實現對分散式系統的監控程式,從而及時地發現系統中出現的延遲升高問題並找出系 統效能瓶頸的根源。
除了面向開發的 API 介面之外,它也提供了方便的UI元件來幫助我們直觀的搜尋跟蹤資訊和分析請求 鏈路明細,比如:可以查詢某段時間內各使用者請求的處理時間等。
Zipkin 提供了可插拔資料儲存方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。
上圖展示了 Zipkin 的基礎架構,它主要由 4 個核心元件構成:
- Collector:收集器元件,它主要用於處理從外部系統傳送過來的跟蹤資訊,將這些資訊轉換為 Zipkin內部處理的 Span 格式,以支援後續的儲存、分析、展示等功能。
- Storage: 儲存元件,它主要對處理收集器接收到的跟蹤資訊,預設會將這些資訊儲存在記憶體中, 我們也可 以修改此儲存策略,通過使用其他儲存元件將跟蹤資訊儲存到資料庫中。
- RESTful API:API 元件,它主要用來提供外部訪問介面。比如給客戶端展示跟蹤資訊,或是外接 系統訪問以實現監控等。
- Web UI:UI 元件, 基於API元件實現的上層應用。通過UI元件使用者可以方便而有直觀地查詢和分 析跟蹤資訊。
Zipkin分為兩端,一個是 Zipkin服務端,一個是 Zipkin客戶端,客戶端也就是微服務的應用。 客戶端會 配置服務端的 URL 地址,一旦發生服務間的呼叫的時候,會被配置在微服務裡面的 Sleuth 的監聽器監 聽,並生成相應的 Trace 和 Span 資訊傳送給服務端。
6.3.2 ZipKin服務端安裝
第1步: 下載ZipKin的jar包
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin- server&v=LATEST&c=exec
訪問上面的網址,即可得到一個jar包,這就是ZipKin服務端的jar包 第2步: 通過命令列,輸入下面的命令啟動ZipKin Server
java -jar zipkin-server-2.12.9-exec.jar
第3步:通過瀏覽器訪問 http://localhost:9411訪問
6.3.3 Zipkin客戶端整合
ZipKin客戶端和Sleuth的整合非常簡單,只需要在微服務中新增其依賴和配置即可。
第1步:在每個微服務上新增依賴
第2步:新增配置
第3步: 訪問微服務
http://localhost:7000/order-serv/order/prod/1
第4步: 訪問zipkin的UI介面,觀察效果
第5步:點選其中一條記錄,可觀察一次訪問的詳細線路。
6.4 ZipKin資料持久化
Zipkin Server預設會將追蹤資料資訊儲存到記憶體,但這種方式不適合生產環境。Zipkin支援將追蹤 資料持久化到mysql資料庫或elasticsearch中。
6.4.1 使用mysql實現資料持久化
第1步: 建立mysql資料環境
CREATE TABLE IF NOT EXISTS zipkin_spans
( `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query' ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate'; ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations'; ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds'; ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames'; ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
CREATE TABLE IF NOT EXISTS zipkin_annotations ( `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit', `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id', `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id', `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1', `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB', `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation', `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp', `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null', `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address', `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null') ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds'; ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces'; ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job'; CREATE TABLE IF NOT EXISTS zipkin_dependencies ( `day` DATE NOT NULL, `parent` VARCHAR(255) NOT NULL, `child` VARCHAR(255) NOT NULL, `call_count` BIGINT ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);
第2步: 在啟動ZipKin Server的時候,指定資料儲存的mysql的資訊
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql – MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root - -MYSQL_PASS=root
6.4.2 使用elasticsearch實現資料持久化
第1步: 下載elasticsearch 下載地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-8-4
第2步: 啟動elasticsearch
第3步: 在啟動ZipKin Server的時候,指定資料儲存的elasticsearch的資訊
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=elasticsearch --ES- HOST=localhost:9200
相關文章
- 鏈路追蹤
- skywalking鏈路追蹤
- go的鏈路追蹤Go
- DHorse的鏈路追蹤
- Spring Cloud 鏈路追蹤SpringCloud
- golang 接入鏈路追蹤(opentracing)Golang
- Istio Trace鏈路追蹤方案
- Go 鏈路追蹤入門 OpentelemetryGo
- 微服務鏈路追蹤元件 SkyWalking微服務元件
- 分散式鏈路追蹤技術分散式
- 日誌收集和鏈路追蹤:skywalking
- 鏈路追蹤_SkyWalking的部署及使用
- 鏈路追蹤(Tracing)的前世今生(上)
- 一文讀懂鏈路追蹤
- 分散式鏈路追蹤的利器——Zipkin分散式
- zipkin分散式鏈路追蹤介紹分散式
- BOS分散式鏈路追蹤產品揭秘分散式
- Dubbo日誌鏈路追蹤TraceId選型
- Go - 實現專案內鏈路追蹤Go
- 【剖析 | SOFARPC 框架】系列之鏈路追蹤剖析RPC框架
- 使用篇丨鏈路追蹤(Tracing)很簡單:鏈路拓撲
- (16)go-micro微服務jaeger鏈路追蹤Go微服務
- Rust 語言的全鏈路追蹤庫 tracingRust
- AsyncLocal<T>在鏈路追蹤中的應用
- net core 微服務框架 Viper 呼叫鏈路追蹤微服務框架
- Jaeger Client Go 鏈路追蹤|入門詳解clientGo
- Go - 實現專案內鏈路追蹤(二)Go
- go-kit微服務:服務鏈路追蹤Go微服務
- 利用Spring Boot實現微服務的鏈路追蹤Spring Boot微服務
- Asp.Net Core&Jaeger實現鏈路追蹤ASP.NET
- 微服務 Zipkin 鏈路追蹤原理(圖文詳解)微服務
- Jaeger鏈路追蹤在專案中的應用
- .NET6接入Skywalking鏈路追蹤完整流程
- 鏈路追蹤技術的應用及實踐
- 註解列印日誌和資料鏈路追蹤
- 分散式鏈路追蹤自從用了SkyWalking,睡得真香!分散式
- go-zero的全鏈路追蹤與超時Go
- 分散式鏈路追蹤框架的基本實現原理分散式框架