23、SpringCloud Zipkin
一、简介
Zipkin是一个全链路跟踪工具,可以用来监控微服务集群中调用链路的通畅情况,聚合各业务系统调用延迟数据,达到链路调用监控跟踪
如图,在复杂的调用链路中假设存在一条调用链路响应缓慢,如何定位其中延迟高的服务呢?
(1)日志: 通过分析调用链路上的每个服务日志得到结果
(2)zipkin:使用zipkin的web UI可以一眼看出延迟高的服务
二、前提
SpringCloud解决方案下,存在两个子项目,并在一个项目中使用RestTemplate或者Feign等方法调用另外一个项目中的接口。
三、模块
如图所示,各业务系统在彼此调用时,将特定的跟踪消息传递至zipkin,zipkin在收集到跟踪信息后将其聚合处理、存储、展示等,用户可通过web UI方便 获得网络延迟、调用链路、系统依赖等等。zipkin主要设计到四个组件 collector storage search web UI
(1)Collector接收各service传输的数据
(2)Cassandra作为Storage的一种,也可以是mysql等,默认存储在内存中,配置cassandra
(3)Query负责查询Storage中存储的数据,提供简单的JSON API获取数据,主要提供给web UI使用
(4)Web 提供简单的web界面
使用zipkin涉及几个概念
(1)Span
基本工作单元,一次链路调用(可以是RPC,DB等没有特定的限制)创建一个span,通过一个64位ID标识它, span通过还有其他的数据,例如描述信息,时间戳,key-value对的(Annotation)tag信息,parent-id等,其中parent-id 可以表示span调用链路来源,通俗的理解span就是一次请求信息。
(2)Trace
类似于树结构的Span集合,表示一条调用链路,存在唯一标识
(3)Annotation
注解,用来记录请求特定事件相关信息(例如时间),通常包含四个注解信息
cs - Client Start,表示客户端发起请求
sr - Server Receive,表示服务端收到请求
ss - Server Send,表示服务端完成处理,并将结果发送给客户端
cr - Client Received,表示客户端获取到服务端返回信息
(4) BinaryAnnotation
提供一些额外信息,一般已key-value对出现
概念说完,来看下完整的调用链路:
上图表示一请求链路,一条链路通过Trace Id唯一标识,Span标识发起的请求信息,各span通过parent id 关联起来,如图:
整个链路的依赖关系如下:
成链路调用的记录后,如何来计算调用的延迟呢,这就需要利用Annotation信息
计算方式:
sr-cs 得到请求发出延迟
ss-sr 得到服务端处理延迟
cr-cs 得到真个链路完成延迟
四、扩展
brave: 作为各调用链路,只需要负责将指定格式的数据发送给zipkin即可,利用brave可快捷完成操作,但是需要调用方和被调用方同时调用发现必备信息。相关资料可以自行查阅。
五、实战
Zipkin全链路跟踪信息是我们关注的问题,他可以存储在内存中(默认)、数据库中(如mysql)、rebbit中、Cassandra(开源分布式NoSQL数据库)、elasticsearch(基于Lucene的搜索分布式能力的搜索服务器)。本文中我们将介绍如何把全链路跟踪信息存储在内存以及mysql中(当然,数据量大的时候存储在mysql是非常耗时的事情,生产环境不建议使用)。
(1)存储在内存中
存储在内存中是非常简单的,只需要添加依赖包,简单配置一下即可
第一步,pom.xml引入依赖
父项目依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 基本信息 -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.easystudy</groupId>
<artifactId>spring-zipkin-demon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>zipkin演示示例</name>
<description>zipkin是一个全链路跟踪工具</description>
<!-- spring boot项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 项目属性 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
<!--<spring-cloud.version>Finchley.BUILD-SNAPSHOT</spring-cloud.version>-->
<lombok.version>1.16.20</lombok.version>
</properties>
<!-- 项目依赖管理声明,统一管理项目依赖的版本信息,继承项目无需声明版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 项目依赖 -->
<dependencies>
<!-- spring web: springMVC依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring boot测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 监控系统健康情况的工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 修改自动检测加载工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- RESTFul接口文档:通过接口访问文档:http://localhost:8762/swagger-ui.html,8762为服务配置的监听端口,默认8080-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
<!--Lombok:消除模板代码-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!-- 编译插件 -->
<build>
<plugins>
<!-- SpringBoot编译插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- 远程仓库:中央仓库找不到时候,从远程仓库中查找 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<modules>
<module>spring-zipkin-server</module>
<module>spring-zipkin-service</module>
<module>spring-zipkin-eureka</module>
<module>spring-zipkin-customer</module>
<module>spring-zipkin-server-inmemory</module>
</modules>
</project>
本项目依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 基本信息 -->
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-zipkin-server-inmemory</artifactId>
<name>全链路跟踪服务</name>
<description>保存在内容中</description>
<!-- 父项目 -->
<parent>
<groupId>com.easystudy</groupId>
<artifactId>spring-zipkin-demon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!-- 项目强制依赖 -->
<dependencies>
<!-- log4f-slf4j与logback库冲突:排除对应日志库,需要自己添加log4j-slf4j-impl-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.9.4</version>
</dependency>
</dependencies>
</project>
注意: 在创建Spring Boot工程时,我们引入了spring-boot-starter,其中包含了spring-boot-starter-logging,该依赖内容就是Spring Boot默认的日志框架Logback,所以我们在引入log4j之前,需要先排除该包的依赖,再引入log4j的依赖。如:‘
’<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
这里可能是zipkin已经包含日志库,所以与spring-boot-starter中的logback依赖的log4f冲突,导致无法启动,所以这里需要排除对应日志库。
第二步,application.yml配置
#服务器端口配置
server:
port: 8672
spring:
application:
#应用名称
name: zipkin-server
#不指定类型,默认存储在内存中
#zipkin:
# storage:
# #存储类型为mysql
# type: mysql
#spring cloud也提供了spring-cloud-sleuth来方便集成zipkin实现
#这里表示当前程序不使用sleuth
#生产过程中调用数据量非常的大,mysql存储并不是很好的选择,
#这时我们可以采用elasticsearch进行存储
#sleuth:
# enabled: false
#去除控制台异常
management:
metrics:
web:
server:
auto-time-requests: false
第三步,应用程序入口。
@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class, args);
}
}
(2)存储在mysql中
第一步,系统pom.xml依赖配置
父项目同上,此处列举改项目依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 项目基本信息 -->
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-zipkin-server</artifactId>
<name>zipkin server</name>
<description>负责数据收集以及信息展示功能</description>
<!-- 父项目 -->
<parent>
<groupId>com.easystudy</groupId>
<artifactId>spring-zipkin-demon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!-- 项目依赖 -->
<dependencies>
<!-- log4f-slf4j与logback库冲突:排除对应日志库,需要自己添加log4j-slf4j-impl-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- zipkin全链路惊恐 -->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.9.4</version>
</dependency>
<!-- zipkin的mysql存储 -->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-mysql</artifactId>
<version>2.9.4</version>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- HikariCP 连接池依赖,从父依赖获取额版本 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<!-- <scope>runtime</scope> -->
</dependency>
</dependencies>
</project>
此处使用了mysql并使用HikariCP连接池。
第二步,系统配置application.yml
#服务器端口配置
server:
port: 8672
spring:
application:
#应用名称
name: zipkin-server
datasource:
name: zipkin
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/zipkin?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: root
#会根据脚本创建数据库-测试不会-傻B
#配置在数据库创建完以后,可以删除,不然每次都会寻找这个sql,耗费时间
#schema: classpath:/mysql.sql
#是否启动时候创建数据库
initialize: false
continue-on-error: true
zipkin:
storage:
#存储类型为mysql
type: mysql
#spring cloud也提供了spring-cloud-sleuth来方便集成zipkin实现
#这里表示当前程序不使用sleuth
#生产过程中调用数据量非常的大,mysql存储并不是很好的选择,
#这时我们可以采用elasticsearch进行存储
sleuth:
enabled: false
#去除控制台异常
management:
metrics:
web:
server:
auto-time-requests: false
注意,这里需要配置指定类型为mysql存储,默认使用内存存储的,另外指定非内存存储的死后sleuth.enabled必须为false
创建数据库:如果使用mysql存储,必须手动创建对应数据库,然后配置数据库连接(如上为zipkin数据库),数据库建表语句如下:
-- ----------------------------
-- create database zipkin
-- ----------------------------
set charset utf8;
create database if not exists zipkin character set UTF8;
use zipkin;
-- ---------------------------------------------------
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`);
注意: 这里的语句是最新的,可能互联网上其他文章中说明的表欠缺字段,到时zipkin保存链路跟踪信息失效,注意!
(3)使用RestTemplate或者Feign调用端配置zipkin客户端监控
依赖配置pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 项目基本信息 -->
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-zipkin-customer</artifactId>
<name>service customer</name>
<description>服务客户端</description>
<!-- 父项目 -->
<parent>
<groupId>com.easystudy</groupId>
<artifactId>spring-zipkin-demon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!-- 项目强依赖 -->
<dependencies>
<!-- spring cloud 客户注册 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 负载 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<!-- 远程调用 feign必须依赖ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<!-- 添加sleuth全链路依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- 添加sleuth全链路追踪监控依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
</project>
系统配置文件application.yml配置:
#服务配置
server:
#监听端口
port: 8764
#servlet:
#context-path: /auth
spring:
application:
#服务名称
name: customer
#zipkin客户端配置
sleuth:
#采样率设置
sampler:
#接口调用采样概率[两次抓一次]
probability: 0.5
#分布式系统跟踪服务
zipkin:
base-url:http://localhost:8672
#eureka集群配置
eureka:
instance:
#将IP注册到Eureka Server上,如果不配置就是机器的主机名
prefer-ip-address: true
#实例名定义为:"ip:port" 如果spring.cloud.client.ipAddress获取不到则使用spring.cloud.client.ip_address
#instance-id: ${spring.cloud.client.ip_address}:${server.port}
#隔多久去拉取服务注册信息,m默认30s
registry-fetch-interval-seconds: 30
#client发送心跳给server端的频率,m默认30s,如果server端leaseExpirationDurationInSeconds
#后没有收到client的心跳,则将摘除该instance
lease-renewal-interval-in-seconds: 10
#表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,
#在这个时间内若没收到下一次心跳,则将移除该instance,默认是90秒
lease-expiration-duration-in-seconds: 30
#eureka客户端配置
client:
#注册到eureka服务器地址
service-url:
#可以配置多个
#defaultZone: http://mss-eureka1:9010/eureka/,http://mss-eureka2:9011/eureka/
defaultZone:http://localhost:8761/eureka/
# ----Spring Boot Actuator:监控系统配置
endpoints:
health:
sensitive: false
enabled: false
shutdown:
#Spring Boot Actuator的shutdown endpoint默认是关闭的
enabled: true
#自定义api地址:host:port/shutdown就可以实现优雅停机
path: /shutdown
#使用密码验证-项目中添加的有Spring Security,所有通过HTTP暴露的敏感端点都会受到保护
#默认情况下会使用基本认证(basic authentication,用户名为user,密码为应用启动时在控制台打印的密码)
sensitive: true
management:
security:
#刷新时,关闭安全验证
enabled: false
# ----Spring Boot Actuator:监控系统配置
#安全校验
security:
oauth2:
resource:
#本来spring security的基础上使用了spring security oauth2,控制/api下的请求
#但是spring security的资源控制和spring securtiy oauth2的资源控制会互相覆盖
#如果配置添加了security.oauth2.resource.filter-order=3,则使用spring security的控制,反之则为oauth2的控制
filter-order: 3
#系统日志配置
logging:
#日志路径
config: classpath:logback.xml
#不同组件的日志显示级别
level:
org:
springframework:
web: info
#feign 默认关闭熔断,请看HystrixFeignConfiguration
feign:
hystrix:
#启用熔断机制
enabled: true
#熔断配置
hystrix:
command:
default:
execution:
isolation:
thread:
#设置API网关中路由转发请求的HystrixCommand执行超时时间
#在zuul配置了熔断fallback的话,熔断超时也要配置,不然如果你配置的ribbon超时时间大于熔断的超时,那么会先走熔断,相当于你配的ribbon超时就不生效了
#这里面ribbon和hystrix是同时生效的,哪个值小哪个生效,另一个就看不到效果了
timeoutInMilliseconds: 60000
#ribbon负载均衡配置
ribbon:
#设置路由转发请求的时候,创建请求连接的超时时间
ReadTimeout: 30000
#用来设置路由转发请求的超时时间
ConnectTimeout: 60000
# 最大重试次数
MaxAutoRetries: 2
# 重试下一服务次数[排除第一台服务器]
MaxAutoRetriesNextServer: 0
注意:这里只需要配置spring.zipkin.base-url即可;
使用:
* eureka: http://localhost:8671
* zipkin: http://localhost:8672
* service: http://localhost:8673
* consumer:http://localhost:8674
*
* 启动:
* 1、eureka--》service--》zipkin--》consumer
* 2、访问consumer(通过feign访问service一个链路被zipkin监控。一条链路可以无限制长度,也即是可以多层嵌套)
* 3、使用http://localhost:8672访问zipkin查看链路状况(生产环境不要使用mysql数据库存储,量大效率低下,建议使用sleuth)
六、总结
经过测试得出如下结论:
(1)zipkin服务什么时候启动都没关系,配置了zipkin服务的终端在zipkin启动后会自动连接上去
(2)zipkin并不是每次请求接口都是会记录请求耗时的,是采样提取的,可以通过spring.sleuth.sampler.probability=0.5 指定抽样比例,配置才客户端,而不是服务器
(3)要记录客户端的接口请求,客户端依赖zipkin的客户端包即可,接口的服务提供这不需要依赖zipkin相关包,也就是说使用zipkin记录的终端才需要对应依赖。