随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何快读定位服务故障点,以对症下药。于是就有了分布式系统调用跟踪的诞生。
现今业界分布式服务跟踪的理论基础主要来自于 Google 的一篇论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,使用最为广泛的开源实现是 Twitter 的 Zipkin,为了实现平台无关、厂商无关的分布式服务跟踪,CNCF 发布了布式服务跟踪标准 Open Tracing。国内,淘宝的“鹰眼”、京东的“Hydra”、大众点评的“CAT”等
一. 简介
1. Dapper的分布式跟踪
图:这个路径由用户的X请求发起,穿过一个简单的服务系统。用字母标识的节点代表分布式系统中的不同处理过程。
分布式服务的跟踪系统需要记录在一次特定的请求后系统中完成的所有工作的信息。举个例子,上图展现的是一个和5台服务器相关的一个服务,包括:前端(A),两个中间层(B和C),以及两个后端(D和E)。当一个用户(这个用例的发起人)发起一个请求时,首先到达前端,然后发送两个RPC到服务器B和C。B会马上做出反应,但是C需要和后端的D和E交互之后再返还给A,由A来响应最初的请求。对于这样一个请求,简单实用的分布式跟踪的实现,就是为服务器上每一次发送和接收动作收集跟踪标识符(message identifiers)和时间戳(timestamped events)。
分布式链路跟踪的术语:
1)Span:基础工作单元,例如发送一个RPC请求是一个span,返回一个RPC响应也是一样;Span都有一个64位的唯一标识ID,span也包含其他数据,如描述、时间戳事件、键值注解。Span可以启动和停止,同时追踪时间信息;一但创建了span,就必须在将来某个点停止它。一个trace最先开始的span叫做root span,该span的ID等于这个trace的ID.
2) Trace:一组span的树形结构。
3)Annotation:用来记录一段时间内发生的事件。使用Brave工具,我们不需要再为Zipkin设置特殊事件,用来理解谁是客户端、谁是服务端、请求从哪里开始以及在哪里结束。出于学习的目的,标记出这些事件用于突出发生了哪些动作。
cs: Client Send, 客户端发送了一个请求,这个注解表示span的开始;
sr: Server Received, 服务端收到这个请求并开始处理它,当前时间戳减去cs的时间戳表示网络延迟;
ss: Server send, 该注解表示请求处理完成(客户端收到响应),当前时间戳-sr的时间戳=服务端处理请求所用时间;
cr: Client Received, 表示span的结束,客户端成功接收到服务端的响应。当前时间戳-cs的时间戳=整个请求所需时间。
2. Spring Cloud Sleuth
Spring Cloud Sleuth 是 Spring Cloud 的一个组件,它的主要功能是在分布式系统中提供服务链路追踪的解决方案。Spring Cloud Sleuth集成了Zipkin(spring-cloud-sleuth-zipkin)。
Spring Cloud Sleuth的Span和Trace的流程图:
采样率:
另外在分布式链路跟踪中有一个比较关键的设计,就是采样率。当服务请求量很大时,可以设置采样率来控制损耗。如果使用spring-cloud-sleuth-zipkin.,可配置spring.sleuth.sampler.probability,值范围0.0~1.0,默认0.1
3. Zipkin
Zipkin是Twitter的一个开源项目,用来收集服务器上的链路跟踪数据,并通过它提供的API接口来辅助查询跟踪数据以分布式系统的监控程序,通过UI组件帮助我们及时发现系统中出现的延迟升高问题以及系统性能瓶颈根源。
Zipkin包含4个组件:
下图是用户发起请求一个span的生成过程,并上报给Collector:
1)记录tags
2)将trace信息增加到http headers中
3)记录时间戳
4)发送带有trace header的请求,客户端处理请求
5)调用结束,记录花费时长,并返回给用户
6)异步组装span信息,并上报给collector
二、 zipkin server端
下载地址:https://github.com/openzipkin/zipkin/tree/master/zipkin-server
下载后启动:java -jar zipkin-server-2.14.2-exec.jar
访问UI:http://127.0.0.1:9411/
三、zipkin client,在需要跟踪的服务中加入zipkin
1. pom.xml
org.springframework.cloud
spring-cloud-starter-zipkin
2. application.properties
# zipkin服务端地址
spring.zipkin.base-url=http://localhost:9411/
# 采样率
spring.sleuth.sampler.probability=1.0
# zipkin上报方式:web,rabbit,kafka,默认web,但是当pom中引入mq后,必须指定上报方式
spring.zipkin.sender.type=web
3. 当前测试分别对eureka_zuul(A), eureka_feign(B), eureka_client(C)进行了改造,三者关系是A调用B,B调用C。
1)访问A的接口http://127.0.0.1:9301/feign/sayHello?token=1
2) 查看zipkin服务端UI:http://localhost:9411/
上图可以看出,三个服务已经正常接入到zipkin服务端,访问请求也进行了跟踪并生成了trace。
3)点击trace查看详情,列出所有的span,并可以查看每个span的详细信息
参考:
https://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html#_spring_cloud_sleuth
http://www.ityouknow.com/springcloud/2018/02/02/spring-cloud-sleuth-zipkin.html
http://bigbully.github.io/Dapper-translation/ Dapper翻译
https://ai.google/research/pubs/pub36356 Dapper原文
https://zipkin.io/pages/architecture.html zipkin官网