1、什麼是ZipKin
Zipkin 是一個根據 Google 發表的論文“ Dapper” 進行開源實現的分散式跟蹤系統。 Dapper是Google 公司內部的分散式追蹤系統,用於生產環境中的系統分散式跟蹤。 Google在其論文中對此進行了解釋,他們“構建了Dapper,以向Google開發人員提供有關複雜分散式系統行為的更多資訊。”從不同角度觀察系統對於故障排除至關重要,在系統複雜且分散式的情況下更是如此。Zipkin可幫助您準確確定對應用程式的請求在哪裡花費了更多時間。無論是程式碼內部的呼叫,還是對另一服務的內部或外部API呼叫,您都可以對系統進行檢測以共享上下文。微服務通常透過將請求與唯一ID相關聯來共享上下文。此外,在系統太複雜的情況下,可以選擇僅使用樣本追蹤 (sample trace ,一種佔用資源比例更低的追蹤方式) 來減少系統開銷。
官網地址: https://zipkin.io/
Github地址:https://github.com/openzipkin/zipkin
2、安裝Zipkin
在 SpringBoot 2.x 版本後就不推薦自定義 zipkin server 了,推薦使用官網下載的 jar 包方式也就是說我們不需要編寫一個zipkin服務了,而改成直接啟動jar包即可。
老版本jar下載地址:
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
老版本檢視其他版本資訊下載
https://central.sonatype.com/artifact/io.zipkin.java/zipkin-server/versions
最新版本的服務jar下載地址:
https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
最新版本檢視其他版本資訊下載
https://central.sonatype.com/artifact/io.zipkin/zipkin-server/versions
下載快速啟動指令碼:
https://zipkin.io/quickstart.sh
這裡使用ZipKin老版本:zipkin-server-2.12.9-exec.jar
執行:
java -jar zipkin-server-2.12.9-exec.jar
# 或整合RabbitMQ
java -jar zipkin-server-2.12.9-exec.jar --zipkin.collector.rabbitmq.addresses=127.0.0.1
3、資訊持久化啟動
鏈路資訊預設是存在記憶體中,下一次ZipKin重啟後資訊就會消失,所以需要資訊持久化。官方提供了Elasticsearch方式與Mysql兩種儲存方式。本篇使用Mysql進行持久化,在正式環境推薦使用Elasticsearch進行持久化。首先建立一個zipkin資料庫,然後下載資料庫指令碼: https://github.com/openzipkin/zipkin/blob/2.12.9/zipkin-storage/mysql-v1/src/main/resources/mysql.sql 或者複製以下sql語句在zipkin資料庫中執行。
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',
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(`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;
啟動命令:
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=1234qwer
啟動成功訪問服務:http://127.0.0.1:9411/zipkin/
4、微服務整合Zipkin
4.1、 引入Maven依賴
<!--依賴包含了sleuth,所以不需要再單獨引入sleuth-->
<!-- sleuth :鏈路追蹤器 zipkin :鏈路分析器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--如果上面依賴飄紅引不進來,那麼原因可能是你使用的cloud版本已經移除了spring-cloud-starter-zipkin 則需要引入以下依賴-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-sleuth</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-sleuth-zipkin</artifactId>-->
<!-- </dependency>-->
4.2、 配置ZipKin資訊
使用者模組配置:
spring:
profiles:
active: dev
application:
# 服務名稱
name: user-service-model
zipkin:
enabled: true #是否啟用
#zipkin服務所在地址
base-url: http://127.0.0.1:9411/
sender:
type: web #使用http的方式傳輸資料到, Zipkin請求量比較大,可以透過訊息中介軟體來傳送,比如 RabbitMQ
#配置取樣百分比
sleuth:
sampler:
probability: 1 # 將取樣比例設定為 1.0,也就是全部都需要。預設是0.1也就是10%,一般情況下,10%就夠用了
訂單模組配置:
spring:
profiles:
active: dev
application:
# 服務名稱
name: order-service-model
zipkin:
enabled: true
#zipkin服務所在地址
base-url: http://localhost:9411/
sender:
type: web #使用http的方式傳輸資料到, Zipkin請求量比較大,可以透過訊息中介軟體來傳送,比如 RabbitMQ
#配置取樣百分比
sleuth:
sampler:
probability: 1 # 將取樣比例設定為 1.0,也就是全部都需要。預設是0.1也就是10%,一般情況下,10%就夠用了
配置成功後,啟動gateway-module、user-module、order-module模組相關服務。啟動成功訪問後臺服務介面,可以看到在zipkin中已經載入了相關請求資訊。
然後我們可以在看看資料庫,檢查下zipkin在資料庫中資訊是否持久化成功。檢視下圖可以發現資料也已經持久化成功了,這樣不管zipkin重啟多少次都不影響資料的展示。
5、ZipKin整合Dubbo
由於專案使用的是dubbo做為各服務模組之間的通訊呼叫,要想zipkin採集到各服務模組的呼叫資訊,所以需要自己去整合。操作也很方便zipkin為我們提供了整合dubbo相關依賴。首先在dubbo提供者和消費者模組中引入maven依賴:
<!--適用於 Dubbo 2.7.X 版本-->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo</artifactId>
</dependency>
<!--適用於 Dubbo 2.6.x-->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
</dependency>
然後在dubbo配置中新增filter屬性設定tracing引數,呼叫方:
dubbo:
application:
name: order-service-model-consumer
consumer:
group: DEFAULT_GROUP
version: 2.0
check: false
filter: tracing #tracingfilter過濾器對dubbo進行追蹤
provider:
filter: tracing #tracingfilter過濾器對dubbo進行追蹤
提供方:
dubbo:
application:
name: user-service-model-provider
protocol:
name: dubbo
port: -1
consumer:
check: false
filter: tracing #tracingfilter過濾器對dubbo進行追蹤
provider:
filter: tracing #tracingfilter過濾器對dubbo進行追蹤
group: DEFAULT_GROUP
version: 2.0
配置成功後,重新啟動專案服務介面可以看出zipkin實現了對dubbo的鏈路追蹤。檢視下圖可以發現該介面呼叫了訂單和使用者兩個服務模組。
點選user-service-model可以檢視出採集資訊詳情。
在zipkin導航選單中,點選依賴可以檢視每個服務模組的依賴資訊。