搭建資料追蹤系統

xiangdong發表於2019-03-02

搭建資料追蹤系統

環境說明

作業系統: CentOS 7.2 64位

1. Zipkin簡介

Zipkin是一款開源的分散式實時資料追蹤系統(Distributed Tracking System),基於 Google Dapper的論文設計而來。其主要功能是聚集來自各個異構系統的實時監控資料。

2. 應用場景

  1. 故障快速定位 通過分析呼叫鏈,可以將一次請求的邏輯軌跡完整清晰的展示出來,通過在開發中在業務日誌中新增呼叫鏈ID,可以通過呼叫鏈結合業務日誌快速定位錯誤資訊。

  2. 服務可用性 通過分析各個環節的平均時延,QPS等資訊,可以找到系統的薄弱環節,對一些模組做調整,例如資料冗餘、鏈路可用等。

  3. 效能分析 在呼叫鏈的各個環節分別新增呼叫時延,可以分析系統的效能瓶頸,進行有針對性的優化。

3. 安裝JDK

安裝資料追蹤軟體Zipkin所需要的JDK環境

執行以下命令安裝JDK

yum install java-1.8.0-openjdk* -y
複製程式碼

安裝完成之後,檢查是否安裝成功

java -version
複製程式碼

4. 安裝Zipkin

新建存放ZIPkin的目錄並進入此目錄

mkdir -p /data/release/zipkin && cd "$_"
複製程式碼

下載Zipkin

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

啟動Zipkin

java -jar zipkin.jar
複製程式碼

==Zipkin 預設監聽 9411 埠, 使用瀏覽器訪問 http://IP:9411 即可看到 Zipkin 自帶的圖形化介面。如果沒有看到Zipkin的圖形化介面,請確保外網的9411埠是否已開==

3. 安裝mysql

Zipkin支援的持久化方案比較多,如: MySQL、 Elasticsearch。我們使用MySQL 5.7來作為持久化方案。

1. 下載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
複製程式碼
2. 設定MySQL密碼

獲取 root 臨時密碼

grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'
複製程式碼

使用上一步的獲得的臨時密碼登入 MySQL

mysql -uroot -p
複製程式碼

更改MySQL的root密碼為dettRoot$123

ALTER USER 'root'@'localhost' IDENTIFIED BY 'dettRoot$123';
複製程式碼

退出MySQL,回到Bash shell

exit;
複製程式碼
3. 初始化Zipkin資料庫指令碼

編寫初始化指令碼

在目錄/data/release/zipkin下建立指令碼檔案zipkin_init.sql

touch 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='dettRoot$123'
複製程式碼

建立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;
複製程式碼
5. 啟動 Zipkin
cd /data/release/zipkin

STORAGE_TYPE=mysql MYSQL_HOST=localhost MYSQL_TCP_PORT=3306 MYSQL_DB=zipkin MYSQL_USER=root MYSQL_PASS='dettRoot$123' 

nohup java -jar zipkin.jar &
複製程式碼

6. 建立具有資料上報能力的Demo

1. 搭建 NodeJS 環境
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -

yum install nodejs -y
複製程式碼
2. 建立Demo目錄

建立/data/release/service_a目錄

mkdir -p /data/release/service_a && cd "$_"
複製程式碼

使用NPM安裝相關依賴,在 /data/release/service_a 目錄下建立並編輯 package.json,參考下面的內容。

touch package.json
複製程式碼

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
複製程式碼

建立並編輯 app.js

在 /data/release/service_a 目錄下建立 app.js,參考下面的內容。

touch app.js
複製程式碼

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
複製程式碼

7. 部署完成

檢視採集到的追蹤資料

使用瀏覽器訪問 http://IP:9411,即可看到剛才訪問產生的追蹤資料。

附1 . 關於微信公眾號

微信公眾號ID:jsj201501

微信公眾號名稱:瞎說開發那些事

感謝您的關注和閱讀,希望這篇文章能為您帶來幫助。

歡迎轉載與分享,也請註明出處。

如果您有需要了解的關於Java開發、RPA的等內容,也可以給我留言或發郵件 (shexd1001@gmail.com)。

公眾號二維碼

附2 . 關於本文作者

本文作者:折(she) 向東

微訊號:wxxdong2102

識別以下二維碼,可以與作者進行更為深入的交流。

搭建資料追蹤系統

相關文章