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

本篇文章爲系列文章,未讀第一集的同學請猛戳這裏:Spring Cloud 系列之 Sleuth 鏈路追蹤(一)

本篇文章講解 Sleuth 基於 Zipkin 存儲鏈路追蹤數據至 MySQL,Elasticsearch 以及使用 MQ 存儲鏈路追蹤數據至 MySQL,Elasticsearch。


存儲追蹤數據

Zipkin Server 默認存儲追蹤數據至內存中,這種方式並不適合生產環境,一旦 Server 關閉重啓或者服務崩潰,就會導致歷史數據消失。Zipkin 支持修改存儲策略使用其他存儲組件,支持 MySQL,Elasticsearch 等。

MySQL

數據庫腳本

打開 MySQL 數據庫,創建 zipkin 庫,執行以下 SQL 腳本。

官網地址:https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

--
-- Copyright 2015-2019 The OpenZipkin Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software distributed under the License
-- is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions and limitations under
-- the License.
--

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;

部署 Zipkin 服務端

添加啓動參數,重新部署服務端:

官網地址:https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_USER=root --MYSQL_PASS=root --MYSQL_DB=zipkin

測試

訪問:http://localhost:9000/order-service/order/1 查看數據庫結果如下:

在 MySQL 模式下,每次啓動服務端時,服務端會從數據庫加載鏈路信息展示至 Web 界面。

RabbitMQ

點擊鏈接觀看:基於 MQ 並存儲鏈路信息至 MySQL 視頻(獲取更多請關注公衆號「哈嘍沃德先生」)

之前的課程中我們已經學習過 RabbitMQ 的詳細使用,這裏不再過多贅述,直接開啓使用即可。

啓動 RabbitMQ 服務器

開啓虛擬機,通過以下命令啓動 RabbitMQ 服務端。

systemctl start rabbitmq-server.service

訪問:http://192.168.10.101:15672/ 使用默認用戶名和密碼 guest

查看隊列,此時無任何隊列。

部署 Zipkin 服務端

添加啓動參數,重新部署服務端:

官網地址:https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_USER=root --MYSQL_PASS=root --MYSQL_DB=zipkin --RABBIT_ADDRESSES=192.168.10.101:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_VIRTUAL_HOST=/ --RABBIT_QUEUE=zipkin

啓動參數中包含 MySQL 和 RabbitMQ 的配置,實現基於 MQ 並存儲鏈路信息至 MySQL,如下圖:

查看隊列

訪問:http://192.168.10.101:15672/#/queues 可以看到已經創建好了 zipkin 隊列。

客戶端添加依賴

官網文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.2.1.RELEASE/reference/html/#sleuth-with-zipkin-over-rabbitmq-or-kafka

<!-- spring cloud zipkin 依賴 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- 消息隊列通用依賴 -->
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
</dependency>

客戶端配置文件

spring:
  zipkin:
    base-url: http://localhost:9411/ # 服務端地址
    sender:
      type: rabbit
    rabbitmq:
      queue: zipkin                  # 隊列名稱
  rabbitmq:
    host: 192.168.10.101             # 服務器 IP
    port: 5672                       # 服務器端口
    username: guest                  # 用戶名
    password: guest                  # 密碼
    virtual-host: /                  # 虛擬主機地址
    listener:
      direct:
        retry:
          enabled: true              # 是否開啓發布重試
          max-attempts: 5            # 最大重試次數
          initial-interval: 5000     # 重試間隔時間(單位毫秒)
      simple:
        retry:
          enabled: true              # 是否開啓消費者重試
          max-attempts: 5            # 最大重試次數
          initial-interval: 5000     # 重試間隔時間(單位毫秒)
  sleuth:
    sampler:
      probability: 1.0               # 收集數據百分比,默認 0.1(10%)

測試

先關閉 Zipkin 服務端,訪問:http://localhost:9000/order-service/order/1 客戶端已將鏈路追蹤數據寫入隊列當中:

啓動 Zipkin 服務端後,隊列中消息被消費。

鏈路追蹤數據被存儲至 MySQL。

Elasticsearch

之前的課程中我們已經學習過 Elasticsearch 的詳細使用,這裏不再過多贅述,直接開啓使用即可。

啓動 Elasticsearch 集羣

本文使用的 Elasticsearch 集羣地址爲:

  • 192.168.10.101:9200
  • 192.168.10.102:9200
  • 192.168.10.103:9200

啓動集羣,訪問:http://192.168.10.101:9200/_cluster/health?pretty 結果如下:

啓動 head 插件,訪問:http://192.168.10.101:9100/ 結果如下:

部署 Zipkin 服務端

添加啓動參數,重新部署服務端:

官網地址:https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=elasticsearch --ES_HOSTS=http://192.168.10.101:9200/,http://192.168.10.102:9200/,http://192.168.10.103:9200/ --RABBIT_ADDRESSES=192.168.10.101:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_QUEUE=zipkin

啓動參數中包含 Elasticsearch 和 RabbitMQ 的配置,實現基於 MQ 並存儲鏈路信息至 Elasticsearch

查看索引庫

訪問:http://192.168.10.101:9100 可以看到已經創建好了 zipkin 索引庫。

客戶端添加依賴

官網文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.2.1.RELEASE/reference/html/#sleuth-with-zipkin-over-rabbitmq-or-kafka

<!-- spring cloud zipkin 依賴 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- 消息隊列通用依賴 -->
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
</dependency>

客戶端配置文件

spring:
  zipkin:
    base-url: http://localhost:9411/ # 服務端地址
    sender:
      type: rabbit
    rabbitmq:
      queue: zipkin                  # 隊列名稱
  rabbitmq:
    host: 192.168.10.101             # 服務器 IP
    port: 5672                       # 服務器端口
    username: guest                  # 用戶名
    password: guest                  # 密碼
    virtual-host: /                  # 虛擬主機地址
    listener:
      direct:
        retry:
          enabled: true              # 是否開啓發布重試
          max-attempts: 5            # 最大重試次數
          initial-interval: 5000     # 重試間隔時間(單位毫秒)
      simple:
        retry:
          enabled: true              # 是否開啓消費者重試
          max-attempts: 5            # 最大重試次數
          initial-interval: 5000     # 重試間隔時間(單位毫秒)
  sleuth:
    sampler:
      probability: 1.0               # 收集數據百分比,默認 0.1(10%)

測試

訪問:http://localhost:9000/order-service/order/1 查看索引庫結果如下:

下一篇我們講解 Sleuth 如何使用 Elasticsearch、Logstash、Kibana 分析追蹤數據,記得關注噢~

本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議

大家可以通過 分類 查看更多關於 Spring Cloud 的文章。


🤗 您的點贊轉發是對我最大的支持。

📢 掃碼關注 哈嘍沃德先生「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~


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