从零开始:zipkin

一、工作环境

操作系统:Ubuntu 16.04

java环境:JDK 1.8

SpringBoot版本:1.5.13

SpringCloud版本:Edgware.SR3

 

二、项目配置

1. zipkin Server

pom.xml


    io.zipkin.java
    zipkin-server


    io.zipkin.java
    zipkin-autoconfigure-ui
    runtime

application.yml

server:
  port: 9411

ZipkinApplication.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zipkin.server.EnableZipkinServer;

@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZipkinApplication.class, args);
    }
}

 

2. zipkin client

pom.xml


    org.springframework.cloud
    spring-cloud-starter-zipkin

application.yml

spring:
  zipkin:
    base-url: http://zipkin-server:9411  //zipkin server的地址
  sleuth:
    sampler:
      percentage: 0.1  //监测比例,默认为0.1,设置为1则为每次http动作都监控,但是对性能会有影响

细心的小伙伴可能发现了zipkin-client除了配置文件并没有对项目文件作任何修改,这是因为zipkin的工作原理是一旦监测到feign或者RestTemplate调用api接口就会自动将当前项目的本次http操作上传到配置文件里的zipkin server中。

因为每个项目的zipkin只能监控当前项目,而一次http会话中必定会有request和response,那么两个项目都需要作为zipkin client添加依赖。

 

三、测试

用postman多访问几次zipkin client的url,防止未监控到数据(我这里被坑惨了。。一直都以为是配置错误导致没数据,警醒后面的小伙伴)

从零开始:zipkin_第1张图片

获取到http数据!

 

四、参考

https://yq.aliyun.com/articles/60165

https://yq.aliyun.com/articles/78128

http://www.cnblogs.com/tietazhan/p/6873784.html

 

五、不定期更新

1. zipkin使用mysql进行持久化

默认情况下zipkin将数据保存在内存中(zipkin.storage.type=mem),一旦重启服务数据全部丢失,不适合生产环境

pom添加依赖



    io.zipkin.java
    zipkin-autoconfigure-storage-mysql


    mysql
    mysql-connector-java


    org.springframework.boot
    spring-boot-starter-jdbc

 application.yml添加数据库相关配置

zipkin:
  storage:
    type: mysql

spring:
  datasource:
    url: jdbc:mysql://${MYSQL_HOST}:${MYSQL_TCP_PORT}/${MYSQL_DB}?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username: ${MYSQL_USERNAME}
    password: ${MYSQL_PASSWORD}
    driver-class-name: com.mysql.jdbc.Driver

 环境变量请根据不同情况自行设置,除了数据库用户名和密码外都有默认配置(用户名和密码默认为空),默认配置如下:

host: ${MYSQL_HOST:localhost}  // 数据库IP
port: ${MYSQL_TCP_PORT:3306}  // 数据库端口
username: ${MYSQL_USER:}  // 用户名
password: ${MYSQL_PASS:}  // 密码
db: ${MYSQL_DB:zipkin}  // 默认连接的数据库名称
max-active: ${MYSQL_MAX_CONNECTIONS:10}  // 数据库最大连接数
use-ssl: ${MYSQL_USE_SSL:false}  // 数据库是否使用ssl连接

zipkin.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';
 
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`);

微服务启动文件添加如下Bean

import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import zipkin.server.EnableZipkinServer;
import zipkin.storage.mysql.MySQLStorage;

@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZipkinApplication.class, args);
    }

    @Bean
    public MySQLStorage mySQLStorage(DataSource datasource) {
        return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build();
    }
}

 注:网上的教程里引入的DataSource是javax.sql.DataSource,但是我引入这个包出现了Could not autowire. There is more than one bean of 'DataSource' type的错误,所以我换成了org.apache.tomcat.jdbc.pool.DataSource,目前没有出现问题。如果有小伙伴出现了异常后果欢迎留言讨论 ╮(╯▽╰)╭

 

小白所学尚浅,文章内容是根据参考+实践理解所得,如果有错误的地方欢迎指正!

你可能感兴趣的:(从零开始)