服务链路追踪
一、服务追踪说明
微服务架构是通过业务来划分服务的,使⽤REST调⽤。对外暴露的⼀个接⼝,可能需要
很多个服务协同才能完成这个接⼝功能,如果链路上任何⼀个服务出现问题或者⽹络超
时,都会形成导致接⼝调⽤失败。
随着业务的不断扩张,服务之间互相调⽤会越来越复杂,它们之间的调⽤关系也许如下:
随着服务的越来越多,对调⽤链的分析会越来越复杂。
二、Zipkin
1、ZipKin是⼀个开放源代码的分布式跟踪系统,由Twitter公司开源,它致⼒于收集服务的
定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。它
的理论模型来⾃于 Google Dapper 论⽂。
2、每个服务向 ZipKin 报告计时数据,ZipKin 会根据调⽤关系通过 ZipKin UI ⽣成依赖关系
图,显示了多少跟踪请求通过每个服务,该系统让开发者可通过⼀个 Web 前端轻松的收
集和分析数据,例如⽤户每次请求服务的处理时间等,可⽅便的监测系统中存在的瓶
颈
三、搭建zipkin服务器
1、创建SpringBoot项⽬(版本2.1.x)
2、添加依赖
<dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> <version>2.11.10</version> </dependency> <!--zipkin界⾯--> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> <version>2.11.10</version> </dependency>
3、在启动类添加 @EnableZipkinServer 注解
@SpringBootApplication @EnableZipkinServer public class ZipkinApplication { public static void main(String[] args) { SpringApplication.run(ZipkinApplication.class, args); } }
4、配置yml
spring: application: name: zipkin server: port: 9411 management: endpoints.web.exposure.include: '*' metrics.web.server.auto-time-requests: false
四、服务中Sleuth配置
1、在服务应⽤中添加Sleuth依赖
<!-- spring-cloud-sleuth-zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
2、在服务应⽤中配置yml
spring:
application:
name: goods-provider
zipkin:
enabled: true
base-url: 'http://localhost:9411'
sleuth:
sampler:
probability: 0.1
五、zipkin服务数据存储
1、创建数据库数据表
CREATE TABLE IF NOT EXISTS zipkin_spans (
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT & quot; Span.timestamp(): epoch micros used for endTs query
and to implement TTL & quot;,
`duration` BIGINT COMMENT & quot; Span.duration(): micros used for minDuration
and maxDuration query & quot;
) ENGINE = InnoDB ROW_FORMAT = COMPRESSED;
ALTER TABLE
zipkin_spans
ADD
UNIQUE KEY(`trace_id`, `id`) COMMENT & quot; ignore insert on duplicate & quot;;
ALTER TABLE
zipkin_spans
ADD
INDEX(`trace_id`, `id`) COMMENT & quot; for joining with zipkin_annotations & quot;;
ALTER TABLE
zipkin_spans
ADD
INDEX(`trace_id`) COMMENT & quot; for getTracesByIds & quot;;
ALTER TABLE
zipkin_spans
ADD
INDEX(`name`) COMMENT & quot; for getTraces
and getSpanNames & quot;;
ALTER TABLE
zipkin_spans
ADD
INDEX(`start_ts`) COMMENT & quot; for getTraces ordering
and range & quot;; CREATE TABLE IF NOT EXISTS zipkin_annotations (
`trace_id` BIGINT NOT NULL COMMENT & quot; coincides with zipkin_spans.trace_id & quot;,
`span_id` BIGINT NOT NULL COMMENT & quot; coincides with zipkin_spans.id & quot;,
`a_key` VARCHAR(255) NOT NULL COMMENT & quot; BinaryAnnotation.key
or Annotation.value if type == -1 & quot;,
`a_value` BLOB COMMENT & quot; BinaryAnnotation.value(),
which must be smaller than 64KB & quot;,
`a_type` INT NOT NULL COMMENT & quot; BinaryAnnotation.type()
or -1 if Annotation & quot;,
`a_timestamp` BIGINT COMMENT & quot; Used to implement TTL; Annotation.timestamp
or zipkin_spans.timestamp & quot;,
`endpoint_ipv4` INT COMMENT & quot; Null when Binary / Annotation.endpoint is null & quot;,
`endpoint_ipv6` BINARY(16) COMMENT & quot; Null when Binary / Annotation.endpoint is null,
or no IPv6 address & quot;,
`endpoint_port` SMALLINT COMMENT & quot; Null when Binary / Annotation.endpoint is null & quot;,
`endpoint_service_name` VARCHAR(255) COMMENT & quot; Null when Binary / Annotation.endpoint is null & quot;
) ENGINE = InnoDB ROW_FORMAT = COMPRESSED;
ALTER TABLE
zipkin_annotations
ADD
UNIQUE KEY(
`trace_id`, `span_id`, `a_key`, `a_timestamp`
) COMMENT & quot; Ignore insert on duplicate & quot;;
ALTER TABLE
zipkin_annotations
ADD
INDEX(`trace_id`, `span_id`) COMMENT & quot; for joining with zipkin_spans & quot;;
ALTER TABLE
zipkin_annotations
ADD
INDEX(`trace_id`) COMMENT & quot; for getTraces / ByIds & quot;;
ALTER TABLE
zipkin_annotations
ADD
INDEX(`endpoint_service_name`) COMMENT & quot; for getTraces
and getServiceNames & quot;;
ALTER TABLE
zipkin_annotations
ADD
INDEX(`a_type`) COMMENT & quot; for getTraces & quot;;
ALTER TABLE
zipkin_annotations
ADD
INDEX(`a_key`) COMMENT & quot; for getTraces & quot;; 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;
ALTER TABLE
zipkin_dependencies
ADD
UNIQUE KEY(`day`, `parent`, `child`);
2、pom依赖
<!-- zipkin-storage-mysql-v1 -->
<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin-storage-mysql-v1</artifactId>
<version>2.11.12</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
3、配置yml
spring:
application:
name: zipkin
datasource:
username: root
password: admin123
driver-class-name: com.mysql.jdbc.Driver
url: 'jdbc:mysql://localhost:3306/zipkin'
zipkin:
storage:
type: mysql