CentOS builds a data tracking system based on ZIPKIN

Reference: Tencent Cloud Manual Experiment https://cloud.tencent.com/developer/labs/lab/10195

Introduction to ZipKin

Zipkin is an open source distributed real-time data tracking system (Distributed Tracking System), based on Google Dapper's paper design, developed and contributed by Twitter company. Its main function is to gather real-time monitoring data from various heterogeneous systems. There are other mature implementations of the distributed tracking system, such as: Naver's Pinpoint, Apache's HTrace, Ali's Hawkeye Tracing, JD's Hydra, Sina's Watchman, Meituan Dianping's CAT, skywalking, etc.

ZipKin architecture

ZipKin can be divided into two parts. One part is zipkin server, which is used for data collection, storage, data analysis and display; zipkin client is a series of client tools that zipkin encapsulates based on different languages ​​and frameworks. These tools complete the tracking of data. The structure of the generation and reporting function is as follows:
Insert picture description here

Zipkin Server mainly includes four modules:

(1) Collector receives or collects the data transmitted by each application
(2) Storage stores the received or collected data, currently supports Memory, MySQL, Cassandra, ElasticSearch, etc., which are stored in memory by default.
(3) API (Query) Responsible for querying the data stored in Storage, providing simple JSON API to obtain data, mainly for web UI use

(4) Web provides a simple web interface

The service tracking process is as follows:

┌─────────────┐ ┌───────────────────────┐  ┌─────────────┐  ┌──────────────────┐
│ User Code   │ │ Trace Instrumentation │  │ Http Client │  │ Zipkin Collector │
└─────────────┘ └───────────────────────┘  └─────────────┘  └──────────────────┘
       │                 │                         │                 │
           ┌─────────┐
       │ ──┤GET /foo ├─▶ │ ────┐                   │                 │
           └─────────┘         │ record tags
       │                 │ ◀───┘                   │                 │
                           ────┐
       │                 │     │ add trace headers │                 │
                           ◀───┘
       │                 │ ────┐                   │                 │
                               │ record timestamp
       │                 │ ◀───┘                   │                 │
                             ┌─────────────────┐
       │                 │ ──┤GET /foo         ├─▶ │                 │
                             │X-B3-TraceId: aa │     ────┐
       │                 │   │X-B3-SpanId: 6b  │   │     │           │
                             └─────────────────┘         │ invoke
       │                 │                         │     │ request   │
                                                         │
       │                 │                         │     │           │
                                 ┌────────┐          ◀───┘
       │                 │ ◀─────┤200 OK  ├─────── │                 │
                           ────┐ └────────┘
       │                 │     │ record duration   │                 │
            ┌────────┐     ◀───┘
       │ ◀──┤200 OK  ├── │                         │                 │
            └────────┘       ┌────────────────────────────────┐
       │                 │ ──┤ asynchronously report span     ├────▶ │
                             │                                │
                             │{
    
                                   │
                             │  "traceId": "aa",              │
                             │  "id": "6b",                   │
                             │  "name": "get",                │
                             │  "timestamp": 1483945573944000,│
                             │  "duration": 386000,           │
                             │  "annotations": [              │
                             │--snip--                        │
                             └────────────────────────────────┘

Instrumented client and server are services that use ZipKin Client respectively. Zipkin Client will send tracking data to Zipkin Server for data storage, analysis and display according to the configuration.

Several concepts of ZipKin

In the trace log, there are several basic concepts spanId, traceId, parentId
traceId: a 16-character string used to determine a trace chain, which remains unchanged in a trace chain.
spanId: Region Id. There may be multiple spanIds in a tracking chain. Each spanId is used to indicate the identity in a certain service and is also a 16-character string.
parentId: The spanId of the cross-service caller will be passed to the callee, and the callee will use the caller's spanId as his parentId, and then generate the spanId by himself.

As shown below:

When the call is first initiated, the traceId and spanId are the same, and the parentId does not exist.
Insert picture description here
The traceId of the callee is the same as the traceId of the caller, the callee will generate its own spanId, and the parentId of the callee is the spanId of the caller
Insert picture description here

Configure the Java environment


Install JDK

Zipkin uses Java1.8 (drag package)

[root@localhost ~]# tar zxf jdk-8u201-linux-x64.tar.gz  
[root@localhost ~]# mv jdk1.8.0_201/ /usr/local/java
[root@localhost ~]# vim /etc/profile
export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre/
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
[root@localhost ~]# rm -rf /usr/bin/java
[root@localhost ~]# source /etc/profile
[root@localhost ~]# java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

Install Zipkin


New directory

[root@localhost ~]# mkdir -p /data/release/zipkin && cd "$_"

Download Zipkin

[root@localhost zipkin]# wget -O zipkin.jar  'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'

Start Zipkin, blocking mode

[root@localhost ~]# java -jar /data/release/zipkin/zipkin.jar

Take MySQL as an example to make a data persistence solution


Install MySQL5.7

Interrupt the above block

Download MySQL

[root@localhost ~]# wget http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm

Install the rpm package

[root@localhost ~]# rpm -Uvh mysql57-community-release-el7-9.noarch.rpm

Install MySQL

[root@localhost ~]# yum install mysql-community-server -y

Start the MySQL service

[root@localhost ~]# systemctl start mysqld

Set MySQL password

[root@localhost ~]# grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'
Tb#phSu!B4hQ
[root@localhost ~]# mysql -uroot -p
# 复制以上的密码即可

Modify MySQL root password

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456.CoM';
Query OK, 0 rows affected (0.02 sec)
mysql> exit
Bye

Initialize the Zipkin database

Write initialization script

Please create zipkin_init.sql in the /data/release/zipkin directory

Sample code: /data/release/zipkin/zipkin_init.sql

[root@localhost ~]# vim /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`);

Log in to MySQL

[root@localhost ~]# mysql -uroot -p123456.CoM

Create a zipkin database and import the sql file of the example just now

mysql> CREATE DATABASE zipkin;
Query OK, 1 row affected (0.01 sec)
mysql> use zipkin;
Database changed
mysql> source /data/release/zipkin/zipkin_init.sql
mysql> show tables;
+---------------------+
| Tables_in_zipkin    |
+---------------------+
| zipkin_annotations  |
| zipkin_dependencies |
| zipkin_spans        |
+---------------------+
3 rows in set (0.00 sec)
mysql> exit
Bye

Start Zipkin

[root@localhost ~]# cd /data/release/zipkin/
[root@localhost zipkin]# STORAGE_TYPE=mysql MYSQL_HOST=localhost MYSQL_TCP_PORT=3306 MYSQL_DB=zipkin \
MYSQL_USER=root MYSQL_PASS='123456.CoM' \
nohup java -jar zipkin.jar > /dev/null 2>&1 &

Create a demo with data reporting capabilities


Install Node.js
Download the source installation package of Node.js

[root@localhost ~]# wget https://npm.taobao.org/mirrors/node/v14.0.0/node-v14.0.0-linux-x64.tar.xz

Unzip the Node.js source code package

[root@localhost ~]# tar xf node-v14.0.0-linux-x64.tar.xz

Add Node.js commands to system environment variables

[root@localhost ~]# mv node-v14.0.0-linux-x64 /usr/local/nodejs
[root@localhost ~]# vim /etc/profile
# 末尾添加
export PATH=$PATH:/usr/local/nodejs/bin
[root@localhost ~]# source /etc/profile
[root@localhost ~]# node -v
v14.0.0

Create Demo directory

[root@localhost zipkin]# mkdir /data/release/service_a

Please create and edit package.json in the /data/release/service_a directory,

Sample code: /data/release/service_a/package.json

[root@localhost zipkin]# cd ../service_a/
[root@localhost service_a]# vim ../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"
  }
}

Installation related dependencies

[root@localhost service_a]# npm install

Create and edit app.js

Please create app.js in the /data/release/service_a directory

[root@localhost service_a]# vim 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\n');
});

app.listen(3001, () => {
    
    
  console.log('service-a listening on port 3001!')
});

Start the service (blocking mode)

[root@localhost service_a]# node app.js
service-a listening on port 3001!

Access 127.0.0.1:3001

[root@localhost ~]# curl 127.0.0.1:3001
hello world

Guess you like

Origin blog.csdn.net/weixin_46152207/article/details/113676519