本文主要是介绍springcloud微服务分布式链路追踪之zipkin实战教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
简介
- 微服务实施的过程一般会进行细粒度的拆分,服务不允许跨库访问,每个微服务全权负责自己的业务领域。但是很多时候一个功能接口需要多个服务互相配合才能完成,这里自然就会用到服务间的调用和依赖关系。往往这种依赖关系随着业务和系统的演进,即使是资深的架构师也很难清楚的画出一份服务调用关系图来。而Spring Cloud Sleuth为Spring Cloud实现了分布式链路跟踪解决方案。
本文将介绍其springcloudsleuth整合zipkin来作为系统的链路追踪工具,内容有
- 链路追踪调用链信息术语介绍
- 搭建链路追踪服务器
- 微服务集成链路追踪客户端进行调用信息收集
- 链路追踪信息采样频率使用说明
- 集成链路追踪调用链生成插件,生成系统调用链关系图
原文:传送门
注:本文基于springcloud2.1.3 Greenwich.RELEASE 版本
参考文章
- Spring Cloud Sleuth官方使用教程
- zipkin-dependencies使用介绍
1、链路追踪调用链信息术语介绍
Span
Span是基本的工作单元。Span包括一个64位的唯一ID,一个64位trace码,描述信息,时间戳事件,key-value 注解(tags),span处理者的ID(通常为IP)。
最开始的初始Span称为根span,此span中span id和 trace id值相同。
个人对span的解读
span可以分为两类:
- 一类是描述服务内部处理这个接口的过程
- 另一类是描述服务间的一次调用过程
举个栗子,client需要调用service1的一个接口,service1又要调用service2的某个接口。
步骤如下:
- service1接收到client的请求(sr),span1
- service1需要调用service2的某个接口(cs),span2
- service2接收到service1的请求(sr),span2
- service2处理接口逻辑,(内部处理过程) span3
- service2返回接口响应给service1(ss),span2
- service1接收到service2的响应结果(cr),span2
- service1再处理完该接口内的内部逻辑,(内部处理过程) span4
- service1再返回给client(ss)。span1
这里就可以分析出
- span1描述了client–>service1之间的调用过程
- span2描述了service1–>service2之间的调用过程
- span3描述了service2自己的业务逻辑处理过程
- span4描述了service1的内部处理过程
Trance
包含一系列的span,它们组成了一个树型结构。从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为止的整个过程
Annotation
用于及时记录存在的事件。常用的Annotation如下
cs - Client Sent:客户端发送一个请求,表示span的开始
sr - Server Received:服务端接收请求并开始处理它。(sr-cs)等于网络的延迟
ss - Server Sent:服务端处理请求完成,开始返回结束给服务端。(ss-sr)表示服务端处理请求的时间
cr - Client Received:客户端完成接受返回结果,此时span结束。(cr-sr)表示客户端接收服务端数据的时间
如果一个服务的调用关系如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x2IOnJ2n-1584002254359)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066157023046128.png)]
那么此时将Span和Trace在一个系统中使用Zipkin注解的过程图形化:
每个颜色的表明一个span(总计7个spans,从A到G),每个span有类似的信息
Trace Id = X #调用链ID,用来标识同一个请求 Span Id = D #调用链中的一个步骤,用来描述接口处理的过程 Client Sent #服务间的调用类型的span的调用过程各个阶段的描述,所以只有服务间调用的span才存在此信息
此span表示span的Trance Id是X,Span Id是D,同时它发送一个Client Sent事件
- 该调用链中各个span之间的关系图如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2Hg8rZV-1584002254360)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066197284006549.png)]
调用链中各个span的说明
在Zipkin中展示了上图的跟踪信息,红框里是对上图调用span的跟踪
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OnfzIJj-1584002254361)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066497886050473.png)]
但是你点击这个trace时,我们只看到4个span
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WUFzb1OO-1584002254363)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066514925091210.png)]
为什么两个界面显示的span数量不同,一个是7,一个4.
- 1 个 spans:来自servier1的接口http:/start 被调用,分别是Server Received (SR) 和 Server Sent (SS) annotations.
- 2 个 spans:来自 service1 调用service2 的 http:/foo 接口。service1 端有两个span,分别为 Client Sent (CS) 和 Client Received (CR) annotations。service2 端也有两个span,分别为Server Received (SR) 和Server Sent (SS) 。物理上他有2个span,但是从逻辑上说这个他们组成一个RPC调用的span。
- 2个span:来自 service2 调用 service3 的 http:/bar 接口,service2 端有两个span,分别为Client Sent (CS) 和 Client Received (CR) annotations。service3 端也有两个span,分别为Server Received (SR) 和Server Sent (SS) 。物理上他有2个span,但是从逻辑上说它们都是同一个RPC调用的span。
- 2个span:来自 service2 调用 service4 的 http:/bar 接口,service2 端有两个span,分别为Client Sent (CS) 和 Client Received (CR) annotations。service4 端也有两个span,分别为Server Received (SR) and Server Sent (SS) 。物理上他有2个span,但是从逻辑上说这个它们都是同一个RPC调用的span。
所以我们计算物理spans有7个:
1个来自 http:/start 被请求
2个来自 service1调用service2
2个来自 service2调用service3
2个来自 service2调用service4.
从逻辑上说,我们只看到4个span:1个来自client发起的接口调用
3个来自服务之间的接口调用
总结:物理span包含了服务内部处理逻辑span和服务间接口调用过程描述span,逻辑span只记录了服务间接口调用过程描述的span。
2、搭建链路追踪服务器
2.1 简介
链路追踪服务将整合zipkin作为链路追踪日志收集服务器,功能特性说明
- 存储组件为Elasticsearch
- 日志收集方式为RabbitMq异步收集
- 配置信息会用到springcloudconfig
- 注册到Eureka注册中心,启用服务发现功能
2.2 pom.xml引入依赖
<?xml version="1.0" encoding="UTF-8"?><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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.danyuanblog.springcloud</groupId><artifactId>spring-cloud-zipkin-server</artifactId><name>spring-cloud-zipkin-server</name><url>http://www.danyuanblog.com</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.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>Greenwich.RELEASE</spring-cloud.version><zipkin-server.version>2.11.8</zipkin-server.version> <zipkin-es.version>2.8.4</zipkin-es.version> </properties><dependencies><!-- Eureka注册中心客户端依赖 --><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-sleuth</artifactId></dependency><!-- zipkin服务器依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-server</artifactId><version>${zipkin-server.version}</version><exclusions><exclusion><artifactId>spring-boot-starter-log4j2</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency> <!-- zipkin管理后台依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-ui</artifactId><version>${zipkin-server.version}</version></dependency><!-- zipkin 整合Elasticsearch存储组件依赖 --><!-- https://mvnrepository.com/artifact/io.zipkin.java/zipkin-autoconfigure-storage-elasticsearch-http --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId><version>${zipkin-es.version}</version></dependency><!-- zipkin使用rabbitmq异步收集调用链信息依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId><version>2.11.8</version></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <!-- 配置中心客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 连接配置中心重试的依赖 --><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></repository><repository><id>Sonatype</id><name>Sonatype Repository</name><url>http://repository.sonatype.org/content/groups/public</url><layout>default</layout><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository><repository><id>Central</id><name>Central Repository</name><url>http://repo1.maven.org/maven2</url><layout>default</layout><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><name>oss.sonatype.org</name><id>oss.sonatype.org</id><url>http://oss.sonatype.org/content/groups/public</url></pluginRepository></pluginRepositories>
</project>
2.3 编辑启动类StartZipkinApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import zipkin2.server.internal.EnableZipkinServer;@EnableZipkinServer
@EnableDiscoveryClient
@SpringBootApplication
public class StartZipkinApplication {public static void main(String[] args) {SpringApplication.run(StartZipkinApplication.class, args);}
}
2.3 配置信息
- 编辑bootstrap.yml
spring:application:name: zipkin-servercloud:#配置中心客户端信息config:discovery:enabled: trueservice-id: config-server label: master fail-fast: trueretry:initial-interval: 2000 #首次重试间隔时间,默认1000毫秒multiplier: 1.1D #下一次重试间隔时间的乘数,比如开始1000,下一次就是1000*1.1=1100max-interval: 2000 #最大重试时间,默认2000max-attempts: 20 #最大重试次数,默认6次
#注册中心客户端信息
eureka:client: serviceUrl: defaultZone: http://localhost:8763/eureka/instance:prefer-ip-address: trueleaseRenewalIntervalInSeconds: 10health-check-url-path: /actuator/healthserver:port: 9411
- 编辑zipkin-server.yml
maxHttpHeaderSize: 8192
spring:sleuth:enabled: false
#采样率,推荐0.1,百分之百收集的话存储可能扛不住sampler:percentage: 1 #100%采集用于测试
zipkin: collector:rabbitmq:addresses: localhostport: 5672username: adminpassword: adminqueue: zipkinstorage: type: elasticsearch #es存储zipkin追踪信息StorageComponent: elasticsearchelasticsearch:hosts: localhost:9200cluster: elasticsearchindex: zipkinindex-shards: 5index-replicas: 1
3、微服务集成链路追踪客户端进行调用信息收集
3.1 功能说明
微服务也需要注册到Eureka注册中心,便于使用服务发现功能
- 链路追踪信息收集功能只依赖于zipkin-server服务名,便于zipkin-server做集群化
- 信息收集采用rabbitmq异步收集
3.2 引入maven依赖
<!-- zipkin链路追踪依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId></dependency><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency>
3.3 配置信息
spring#链路追踪配置zipkin:enabled: true#base-url: http://zipkin-server/ #采用MQ方式收集便不用配置zipkin服务器信息了rabbitmq:queue: zipkinlocator:discovery:enabled: truesender:type: rabbitmqsleuth:sampler:#采样率,推荐0.1,百分之百收集的话存储可能扛不住probability: 1.0
4、链路追踪信息采样频率使用说明
spring.sleuth.sampler.probability
用于设置链路追踪信息采样率
- 测试环境建议配置为1,表示100%收集
- 线上根据实际用户量来配置,如果接口并发比较高,0.1就足够反应整个平台的服务链路情况了
5、集成链路追踪调用链生成插件,生成系统调用链关系图
- 下载依赖包
curl -sSL https://zipkin.io/quickstart.sh | bash -s io.zipkin.dependencies:zipkin-dependencies:LATEST zipkin-dependencies.jar
- 每天定时生成调用链依赖关系图
#生成当前时间前一天的调用链依赖关系图
STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 ES_INDEX=zipkin java -jar zipkin-dependencies.jar `date -u -d '1 day ago' +%F`
然后进入zipkin-server管理后台,进入Dependencies菜单,选择对应的日期范围
- 生成的调用链关系图是根据接口的实际调用情况绘制而成
- 线条越粗代表调用量越大
这篇关于springcloud微服务分布式链路追踪之zipkin实战教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!