docker–zipkin(分布式链路追踪)实践
文章目录
- docker--zipkin(分布式链路追踪)实践
- 前言
- zipkin架构
- 启动服务
- 使用mysql数据库
- springcloud实践
- 引入依赖
- 配置
- 接口实现
- 运行
- 参考
前言
- 官网:OpenZipkin
- zipkin是Twitter基于google的分布式监控系统Dapper(论文)的开发源实现,zipkin用于跟踪分布式服务之间的应用数据链路,分析处理延时,帮助我们改进系统的性能和定位故障
- 搭建 Zipkin 最简单的办法是直接使用 Zipkin 官方的 Docker 镜像。
zipkin架构
启动服务
- 启动服务命令如下
#!/bin/sh
docker run -d \
--restart always \
-v /etc/localtime:/etc/localtime:ro \
-p 9411:9411 \
--name zipkin \
openzipkin/zipkin
- 以上命令即可启动一个zipkin服务,不过数据是放在内存中,一旦重启就数据就消失了,因此这种只适合在测试时使用,生产环境中需要配置持久化,如mysql
使用mysql数据库
- 如果只是为了测试用,那么以上的服务就够用了,但是一旦到生产环境中,那么数据持久化就非常重要了,官方提供了很多支持,在这里我就用mysql来存储了
- 如果你已经有了mysql数据库,那么可以直接用现有的mysql进行建库建表
- 以下方法适用于mysql数据库跟zipkin不在同一台机器上
- 首先创建数据库zipkin,编码使用utf8
- 创建数据库后执行以下sql创建表,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',
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(`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服务了,命令如下
#!/bin/sh
docker run -d \
--restart always \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_USER=root \
-e MYSQL_PASS=password \
-e MYSQL_HOST=192.168.0.8 \
-e STORAGE_TYPE=mysql \
-e MYSQL_DB=zipkin \
-e MYSQL_TCP_PORT=3306 \
--net host \
--name zipkin \
openzipkin/zipkin
- 以上参数需要根据实际情况修改,这里由于使用到数据库,因此网络模式为host;如果使用桥接方式,那么要用link连接到数据库(理论上可行,但自己没测试过,故不做说明)
以上虽然加了共享宿主机的时区,进入到容器内查看date和宿主机也是一样的,但看打印日志的时间还是快了8小时,百思不得其解,望高人指点
springcloud实践
- 实践环境为:
- springboot:2.1.3.RELEASE
- springcloud:Greenwich.SR1
- gradle:5.2.1
引入依赖
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-zipkin'
}
- spring-cloud-starter-zipkin中已包含了spring-cloud-starter-sleuth与spring-cloud-sleuth-zipkin的依赖,所以使用sleuth-zipkin的SpringCloud项目只需添加spring-cloud-starter-zipkin依赖即可
配置
spring:
application:
name: test #在zipkin上显示的服务名,不写则是“default”
zipkin:
base-url: http://192.168.25.169:9411/ #zipkin服务的地址
# sender:
# type: web #网上有人在zipkin上查不到记录,说加上这个即可,但本人亲测不加也是可以查到记录
sleuth:
sampler:
probability: 1.0 #请求的采样率,在测试时为了方便查看可以改为1表示所有请求都记录,但在生产环境中还是建议改为0.1,否则数量太多影响性能
接口实现
- 在程序中简单实现一个接口
@SpringBootApplication
@RestController
public class SleuthApplication {
public static void main(String[] args) {
SpringApplication.run(SleuthApplication.class, args);
}
@GetMapping("/test")
public String abc(){
return "hello";
}
}
运行
- 通过以上两步运行程序即可,此时调用test接口在zipkin服务上并不能马上看到记录,需要等待大约1分钟左右再去刷新
值得注意的是,zipkin的浏览器兼容性还不是很好,在ie和360浏览器上发现显示不了记录,建议使用firefox进行测试,一开始用360浏览器一直看不到记录,害我以为是服务有问题,浪费了大量时间排查
另外,由于时区的问题未解决,因此时间可能要选大一点的才可能查找到