利用Zipkin追蹤Mysql數據庫調用鏈

Profile

概述

在前面:微服務調用鏈追蹤中心搭建 一文中我們利用Zipkin搭建了一個微服務調用鏈的追蹤中心,并且模擬了微服務調用的實驗場景。利用Zipkin的庫Brave,我們可以收集一個客戶端請求從發出到被響應 經歷了哪些組件哪些微服務請求總時長每個組件所花時長 等信息。

本文將講述如何利用Zipkin對Mysql數據庫的調用進行追蹤,這里同樣借助OpenZipkin庫Brave來完成。

注: 本文原載于 My Personal Blog:CodeSheep · 程序羊


擴展ZipkinTool組件

ZipkinTool是在《微服務調用鏈追蹤中心搭建》一文中編寫的與Zipkin通信的工具組件,利用其追蹤微服務調用鏈的,現在我們想追蹤Mysql數據庫調用鏈的話,可以擴展一下其功能。

  • pom.xml添加依賴:
<dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-mysql</artifactId>
        <version>4.0.6</version>
</dependency>
  • 在ZipkinConfiguration類中添加MySQLStatementInterceptorManagementBean
    @Bean
    public MySQLStatementInterceptorManagementBean mySQLStatementInterceptorManagementBean() {
        return new MySQLStatementInterceptorManagementBean(brave().clientTracer());
    }

添加Mysql數據庫訪問的微服務

依然繼承前文:《微服務調用鏈追蹤中心搭建》,我們改造一下文中的ServiceC這個微服務,在其中添加與Mysql數據庫的交互。

  • pom.xml中添加JDBC和Mysql依賴
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
  • application.properties中添加Mysql連接的配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://你的Mysql服務所在IP:3307/test?useSSL=false\
  &statementInterceptors=com.github.kristofa.brave.mysql.MySQLStatementInterceptor\
  &zipkinServiceName=mysqlService
spring.datasource.username=root
spring.datasource.password=XXXXXX
  • Controller中添加JdbcTemplate訪問數據庫的代碼
    @GetMapping("/mysqltest”)
    public String mysqlTest() {
        String name = jdbcTemplate.queryForObject( "SELECT name FROM user WHERE id = 1", String.class );
        return "Welcome " + name;
    }

啟動Mysql數據庫服務

1. 啟動Mysql容器

docker run -d -p 3307:3306 \
-v ~/mysql/data:/var/lib/mysql \
-v ~/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=XXXXXX \
--name mysql mysql

2. 再啟動一個Mysql容器,接入其中做一些設置

  • 首先進入mysql命令行
docker run -it --rm \
--link mysql:mysql mysql \
mysql -hmysql -u root -p
進入Mysql的命令行
  • 接下來創建數據庫zipkin: 用于存放Zipkin所收集的數據
CREATE DATABASE `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’
) 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,
  `error_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

這里創建了三個數據表。

該Sql文件可以從以下鏈接獲得:https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql/src/main/resources/mysql.sql

Sql腳本執行完成后,可以看到zipkin相關的三個表已經建成:

Zipkin相關的三個表
Zipkin相關的三個表
  • 創建數據庫test:用作測試數據庫
CREATE DATABASE `test`
CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `name` varchar(100) DEFAULT NULL ,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET = utf8;

insert into user values (1,”hansonwang99”)

這里插入了一條數據用于實驗。

創建test數據庫并插入一條數據

啟動zipkin服務

docker run -d -p 9411:9411 \
--link mysql:mysql \
-e STORAGE_TYPE=mysql \
-e MYSQL_HOST=mysql \
-e MYSQL_TCP_PORT=3306 \
-e MYSQL_DB=zipkin \
-e MYSQL_USER=root \
-e MYSQL_PASS=XXXXXX \
 --name zipkin openzipkin/zipkin

啟動Mysql數據庫訪問的微服務(即ServiceC)

在瀏覽器中輸入:localhost:8883/mysqltest,如果看到以下輸出,就可以證明數據庫調用操作已經成功了!

數據庫調用操作已經成功

Zipkin追蹤數據庫調用實際實驗

打開Zipkin Web UI,點擊服務名下拉列表能看見已經成功識別了Mysql數據庫調用服務

成功識別Mysql數據庫調用服務
  • 選中mysqlservice后,點擊Find Traces

可以看到 首次查詢 Mysql的調用鏈追蹤信息,有很多

首次查詢Mysql所產生的Traces信息

隨便點開某一個查看:

隨機查看某一個具體的Trace信息
  • 接下來瀏覽器中再次輸入:localhost:8883/mysqltest

目的是再次觸發Mysql的調用,然后再次Find Traces,可以看到追蹤數據類似下圖:包含兩次Mysql的query動作:

兩次Mysql的query動作

點開第一個query查看,其實際上是在 嘗試連接Mysql數據庫

第一個query詳情

點開第二個query查看,發現這里才是 實際查詢業務

第二個query詳情

從圖形化界面上可以清楚地知道每個階段的詳細步驟與耗時,因此可以用來分析哪個SQL語句執行相對較慢。


后記

本文實驗所用源碼已經開源,需要的話請 自取

由于能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!



最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容