搭建基于 ZIPKIN 的数据追踪系统

腾讯云
基础
0 个任务
剩余 0 个名额

你还可以 创建 或者 使用已有 云主机不限时上机

实验内容

Zipkin 是一个分布式数据追踪系统,适用于微服务架构下的调用链路数据采集及分析工作。本实验带您在单机模式搭建基于 Zipkin 的数据追踪系统。

首次可免费使用云主机 1 小时 ,到期后云主机将被重置并退库,若想保留成果请及时留用。

实验资源

云服务器

软件环境

CentOS 7.2 64 位

目录

# 搭建基于 ZIPKIN 的数据追踪系统 ## 配置 Java 环境 > <time>5min ~ 10min</time> ### 安装 JDK Zipkin 使用 Java8 ``` yum install java-1.8.0-openjdk* -y ``` 安装完成后,查看是否安装成功: ``` java -version ``` > <checker type="output-contains" command="which java" hint="JDK 未安装"> > <keyword regex="/usr/bin/java" /> > </checker> ## 安装 Zipkin > <time>10min ~ 20min</time> ### 新建目录 ``` mkdir -p /data/release/zipkin && cd "$_" ``` > <checker type="output-contains" command="ls /data/release" hint="未创建目录"> > <keyword regex="zipkin" /> > </checker> ### 下载 Zipkin ``` wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec' ``` > <checker type="output-contains" command="ls /data/release/zipkin/zipkin.jar" hint="未下载zipkin"> > <keyword regex="zipkin\.jar" /> > </checker> ### 启动 Zipkin ``` java -jar zipkin.jar ``` Zipkin 默认监听 9411 端口, 使用浏览器访问 [http://${runtime.vars.cvmIpAddress}:9411][] 即可看到 Zipkin 自带的图形化界面。[访问遇到问题?][text] > <bubble for="text">请确认此CVM有外网IP且安全组已开通9411端口</bubble> > <checker type="output-contains" command="curl http://127.0.0.1:9411 -I --silent" hint="未启动Zipkin"> > <keyword regex="200|302"></keyword> > </checker> ## 配置 MySQL 数据持久化方案 > <time>10min ~ 20min</time> Zipkin 支持的持久化方案很多,如: Cassandra, MySQL, Elasticsearch。本实验使用 MySQL 5.7 作为数据持久化方案。 ### 安装 MySQL 5.7 使用 `Ctrl + C` 退出上个步骤的 Java 进程并下载 rmp 包 ``` wget http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm ``` 安装 rpm 包 ``` rpm -Uvh mysql57-community-release-el7-9.noarch.rpm ``` 安装 MySQL ``` yum install mysql-community-server -y ``` 启动 MySQL 服务 ``` systemctl start mysqld.service ``` > <checker type="output-contains" command="mysql --version" hint="MySQL 未安装"> > <keyword regex="\d" /> > </checker> > <checker type="output-contains" command="systemctl status mysqld.service" hint="MySQL 未启动"> > <keyword regex="running" /> > </checker> ### 设置 MySQL 密码 获取 root 临时密码 ``` grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}' ``` 使用上一步的获得的临时密码登入 MySQL ``` mysql -uroot -p ``` 设置 MySQL 账户 root 密码[:question][password] ``` ALTER USER 'root'@'localhost' IDENTIFIED BY 'Xx$Zipkin2017'; ``` > <bubble for="password"> > 下面命令中的密码是教程为您自动生成的,为了方便实验的进行,不建议使用其它密码。如果设置其它密码,请把密码记住,在后续的步骤会使用到。 > </bubble> > <checker type="output-contains" command="mysql -u root --password='Xx$Zipkin2017' -e &quot;select 'success' as ''&quot; 2>&amp;1" hint="使用生成的密码无法连接 MySQL,如果你已使用自己的密码完成了设置,请直接进入下一步。"> > <keyword regex="success" /> > </checker> 退出 MySQL, 回到 Bash shell ``` exit; ``` ### 初始化 Zipkin 数据库 编写初始化脚本 请在 `/data/release/zipkin` 目录下[创建 zipkin_init.sql][create_zpk_sql],参考下面的内容。 > <locate for="create_zpk_sql" path="/data/release/zipkin" hint="右击,创建 zipkin_init.sql"></locate> ```sql /// <example verb="create" file="/data/release/zipkin/zipkin_init.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, `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`); ``` 登录 Mysql ``` mysql -u root --password='Xx$Zipkin2017' ``` 创建 Zipkin 数据库 ``` create database zipkin; ``` 切换数据库 ``` use zipkin; ``` 初始化表及索引 ``` source /data/release/zipkin/zipkin_init.sql ``` 执行以下命令会看到`zipkin_annotations`, `zipkin_dependencies`, `zipkin_spans` 三张数据表,说明初始化成功了 ``` show tables; ``` 退出 MySQL, 回到 Bash shell ``` exit ``` > <checker type="output-contains" command="mysql zipkin -u root --password='Xx$Zipkin2017' -e &quot;show tables&quot; 2>&amp;1" hint="使用生成的密码无法连接 MySQL,如果你已使用自己的密码完成了设置,请直接进入下一步。"> > <keyword regex="zipkin_" /> > </checker> ### 启动 Zipkin 注: 此处默认使用实验生成的密码 ``` cd /data/release/zipkin STORAGE_TYPE=mysql MYSQL_HOST=localhost MYSQL_TCP_PORT=3306 MYSQL_DB=zipkin MYSQL_USER=root MYSQL_PASS='Xx$Zipkin2017' \\ nohup java -jar zipkin.jar & ``` > <checker type="output-contains" command="curl http://127.0.0.1:9411 -I --silent" hint="未启动Zipkin"> > <keyword regex="200|302"></keyword> > </checker> ## 创建具有数据上报能力的Demo > <time>10min ~ 20min</time> ### 搭建 NodeJS 环境 ``` curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - yum install nodejs -y ``` > <checker type="output-contains" command="which node" hint="未安装 Node 环境"> > <keyword regex="/usr/bin/node" /> > </checker> ### 创建Demo目录 创建[/data/release/service_a][locate_data_release]目录 > <locate for="locate_data_release" path="/data/release" hint="创建service_a目录"></locate> ``` mkdir -p /data/release/service_a && cd "$_" ``` > <checker type="output-contains" command="ls /data/release" hint="未创建目录"> > <keyword regex="service_a" /> > </checker> ### 使用 NPM 安装相关依赖 请在 `/data/release/service_a` 目录下[创建并编辑 package.json][create_pkgjson],参考下面的内容。 > <locate for="create_pkgjson" path="/data/release/service_a" hint="右击,创建 package.json"></locate> ```json /// <example verb="create" file="/data/release/service_a/package.json" /> { "name": "service_a", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {}, "author": "", "license": "ISC", "dependencies": { "express": "^4.15.3", "zipkin": "^0.7.2", "zipkin-instrumentation-express": "^0.7.2", "zipkin-transport-http": "^0.7.2" } } ``` 安装相关依赖 ``` npm install ``` > <checker type="output-contains" command="ls /data/release/service_a/node_modules" hint="未安装相关依赖"> > <keyword regex="zipkin" /> > </checker> ### 创建并编辑 app.js 请在 `/data/release/service_a` 目录下[创建 app.js][create_appjs],参考下面的内容。 > <locate for="create_appjs" path="/data/release/service_a" hint="右击,创建 app.js"></locate> ```javascript /// <example verb="create" file="/data/release/service_a/app.js" /> const express = require('express'); const {Tracer, ExplicitContext, BatchRecorder} = require('zipkin'); const {HttpLogger} = require('zipkin-transport-http'); const zipkinMiddleware = require('zipkin-instrumentation-express').expressMiddleware; const ctxImpl = new ExplicitContext(); const recorder = new BatchRecorder({ logger: new HttpLogger( { endpoint: 'http://127.0.0.1:9411/api/v1/spans' }) }); const tracer = new Tracer({ctxImpl, recorder}); const app = express(); app.use(zipkinMiddleware({ tracer, serviceName: 'service-a' })); app.use('/', (req, res, next) => { res.send('hello world'); }); app.listen(3000, () => { console.log('service-a listening on port 3000!') }); ``` ### 启动服务 ``` node app.js ``` 该服务监听 3000 端口, 使用浏览器访问 [http://${runtime.vars.cvmIpAddress}:3000][] 后,看到“hello world” 的文本字样说明服务已经正常工作。[访问遇到问题?][text] > <bubble for="text">请确认此CVM有外网IP且安全组已开通3000端口</bubble> > <checker type="output-contains" command="curl http://127.0.0.1:3000 -I --silent" hint="未启动服务"> > <keyword regex="200|302"></keyword> > </checker> ## 部署完成 > <time>3min ~ 5min</time> ### 查看采集到的追踪数据 使用浏览器访问 [http://${runtime.vars.cvmIpAddress}:9411][] 即可看到刚才访问产生的追踪数据。 至此,本入门教程已结束,而 Zipkin 的学习只是一个开始,如有兴趣,可尝试搭建一个基于 Kafka + Zookeeper + Elasticsearch 的分布式服务。 ### 大功告成 恭喜您已经完成了搭建基于 ZIPKIN 的数据追踪系统的学习,您可以留用或者[购买 Linux 版本的 CVM][https://buy.qcloud.com/?fromSource=lab] 继续学习。