SpringCloud 之 Zipkin + Sleuth 服務鏈路追蹤搭建與講解

前言

Zipkin: 負責接收 Sleuth 發來的跟蹤數據,進行存儲,UI 可視化。
Sleuth: 微服務跟蹤(Sleuth)其實是一個工具,它在整個分佈式系統中能跟蹤一個用戶請求的過程(包括數據採集,數據傳輸,數據存儲,數據分析,數據可視化),捕獲這些跟蹤數據,就能構建微服務的整個調用鏈的視圖,這是調試和監控微服務的關鍵工具。

基本概念

Span(跨度): 基本工作單元。我將它理解成一個個的事件節點,它還包含:描述,時間戳等。
Trace(跟蹤): Span 組成的樹狀結構稱爲 TraceTrace 中的所有 Span 都共享該 Trace 的ID。
Annotation(標註): Annotation 用來記錄事件的存在,其中核心 Annotation 用來定義請求的開始和結束。

  • cs(Client Sent): 客戶端發起一個請求,這個註釋指示了一個 Span 的開始。
  • sr(Server Received): 服務端接收請求並開始處理它,如果用 sr 時間戳減去 cs 時間戳便能看出有多少網絡延遲。
  • ss(Server Sent): 註釋請求處理完成(響應已發送給客戶端),如果用 ss 時間戳減去 sr 時間戳便可得出服務端處理請求耗費的時間。
  • cr(Client Received): 預示了一個 Span 的結束,客戶端成功地接收到了服務端的響應,如果用 cr 時間戳減去 cs 時間戳便可得出客戶端從服務端獲得響應所需耗費的整個時間。

Zipkin 安裝

下載 Zipkin-Server.jar

wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'

或者手動下載:Zipkin-Server

啓動 Zipkin 並持久化數據到數據庫

PS:Zipkin 默認存儲在內存裏的,即浪費內存又存在宕機丟失數據的隱患。如果知識跑着玩下,可以直接 java -jar zipkin.jar 直接啓動即可

建表

官方:mysql.sql

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,
  `remote_service_name` VARCHAR(255),
  `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',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

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(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
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 and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
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,
  `error_count` BIGINT,
  PRIMARY KEY (`day`, `parent`, `child`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

啓動

參考:官方文檔

下面我給出我啓動的示例:

  • --STORAGE_TYPE=mysql:類別爲 mysql
  • --MYSQL_HOST=127.0.0.1:設置數據庫 Host
  • --MYSQL_TCP_PORT=7000:設置數據庫端口號
  • --MYSQL_DB=zipkin:設置庫名
  • --MYSQL_USER=root:數據庫賬號
  • --MYSQL_PASS=123456:數據庫密碼
java -jar zipkin.jar \
--STORAGE_TYPE=mysql \
--MYSQL_HOST=127.0.0.1 \
--MYSQL_TCP_PORT=7000 \
--MYSQL_DB=zipkin \
--MYSQL_USER=root \
--MYSQL_PASS=123456

訪問 Zipkin

默認端口爲 9411

http://localhost:9411/zipkin/

在這裏插入圖片描述

客戶端配置

即需要被追蹤的服務新增配置,使得他的調用信息能夠發送到 Zipkin Server

加註解

<!-- sleuth + zipkin -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-sleuth-zipkin</artifactId>
 </dependency>

加配置

spring:
  # zipkin 配置
  zipkin:
    base-url: http://localhost:9411/ # zipkin服務器的地址
    sender:
      type: web  # 設置使用http的方式傳輸數據
  # sleuth 配置
  sleuth:
    sampler:
      probability: 1 # 設置抽樣採集爲100%,默認爲0.1,即10%

基本使用

查找

UI 界面:
在這裏插入圖片描述
點擊一個請求:
可以看到中間經歷了哪些的事件,比如:可以看到 feign-demo 在發送請求到 service-a 前還經歷了一層斷路器 Hystrix,因此我們知道,從這裏開始斷路器開始監控發送給 service-a 的請求,如果這個請求掛了,就進行斷路。
在這裏插入圖片描述點擊一個 Span 詳情:
在這裏插入圖片描述
可以看到更加詳細的調用相求,內容都看得懂,就不多介紹了
在這裏插入圖片描述

依賴

可以看到調用的鏈路
在這裏插入圖片描述
點擊其中一個節點,比如 feign-demo
在這裏插入圖片描述
點擊 Zuul 看看裏面的信息

可以看到我調用了 4 次,還沒有失敗的
在這裏插入圖片描述

請求失敗

來看看如果調用失敗的情況,這裏我把 service-a 服務停止了,因此調用失敗,feign 進行了降級處理
在這裏插入圖片描述
Zipkin-Server 這也可以看到服務調用出現了問題
在這裏插入圖片描述
在這裏插入圖片描述
這裏由於調用失敗,所以異常由自己來處理
在這裏插入圖片描述
點擊進去,可以看到失敗的次數,我剛調用了兩次,因此失敗了兩次
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章