一、分布式链路跟踪
微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题,很快定位。而Spring cloud sleuth组件正是为了解决微服务跟踪的组件。
1.1.什么是链路追踪
链路追踪,就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。
1.2.链路追踪相关产品
常见的链路追踪技术有下面这些:
- cat:由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 集成方案是通过代码埋点的方式来实现监控,比如: 拦截器,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。
- zipkin:由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现。该产品结合spring-cloud-sleuth使用较为简单, 集成很方便, 但是功能较简单。
- pinpoint:Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件, UI功能强大,接入端无代码侵入。
- skywalking:本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件, UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。
- Sleuth:SpringCloud 提供的分布式系统中链路追踪解决方案。
需要注意的是SpringCloud alibaba中并没有提供链路追踪技术,也可以采用Sleuth +Zinkin来做链路追踪解决方案
二、Sleuth概述
2.1.什么是Sleuth
Spring Cloud Sleuth 为 Spring Cloud 实现了分布式跟踪解决方案。兼容 Zipkin,HTrace 和其他基于日志的追踪系统,例如 ELK(Elasticsearch 、Logstash、 Kibana),Spring Cloud Sleuth 提供了以下功能:
-
链路追踪
:通过 Sleuth 可以很清楚的看出一个请求都经过了那些服务,可以很方便的理清服务间的调用关系等。 -
性能分析
:通过 Sleuth 可以很方便的看出每个采样请求的耗时,分析哪些服务调用耗时,当服务调用的耗时随着请求量的增大而增大时, 可以对服务的扩容提供一定的提醒。 -
数据分析
,优化链路:对于频繁调用一个服务,或并行调用等,可以针对业务做一些优化措施。 -
可视化错误
:对于程序未捕获的异常,可以配合 Zipkin 查看。
2.2.Sleuth基本概念
Sleuth基本概念涉及概念: span、Trace、Annotations
-
span:
基本工作单位,每次发送一个远程调用服务就会产生一个 Span。Span 是一个 64 位的唯一 ID。通过计算 Span 的开始和结束时间,就可以统计每个服务调用所花费的时间。。 -
Trace:
一系列 Span 组成的树状结构,一个 Trace 认为是一次完整的链路,内部包含 n 多个 Span。Trace 和 Span 存在一对多的关系,Span 与 Span 之间存在父子关系。 -
Annotations:
用来及时记录一个事件的存在,一些核心 annotations 用来定义一个请求的开始和结束。
- cs - Client Sent:客户端发起一个请求,这个 annotation 描述了这个 span 的开始;
- sr - Server Received:服务端获得请求并准备开始处理它,如果 sr 减去 cs 时间戳便可得到网络延迟;
- ss - Server Sent:请求处理完成(当请求返回客户端),如果 ss 减去 sr 时间戳便可得到服务端处理请求需要的时间;
- cr - Client Received:表示 span 结束,客户端成功接收到服务端的回复,如果 cr 减去 cs 时间戳便可得到客户端从服务端获取回复的所有所需时间。
-
核心
为什么能够进行整条链路的追踪? 其实就是一个 Trace ID 将 一连串的 Span 信息连起来了。根据 Span 记录的信息再进行整合就可以获取整条链路的信息。
三、搭建链路监控步骤
3.1.zipkin
需要说明的是SpringCloud 从F版起不需要自己构建Zipkin Server了,只需下载然后调用jar包即可,下载地址:https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
下载后 运行jar包:
java -jar zipkin-server-2.12.9-exec.jar
如下图所示,表示启动成功:
默认会使用9411端口启动服务,由于部署在本机了,所以通过浏览器访问:http://localhost:9411/zipkin,如下图所示,表示成功访问:
3.2.准备服务提供者
这里还是使用之前的 cloud-provider-payment8001 作为服务提供者
- 需要修改pom,在pom中引入zipkin的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
- 修改application.yml 添加对于zipkin的支持
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
# 采样频率介于0到1之间,1则表示全部采集
probability: 1
如图所示:
- 在controller中添加如下请求:
@GetMapping("/zipkin")
public String paymentZipkin() {
return "hi,我是8001服务提供者";
}
3.3.准备服务消费者
还是利用这里的 cloud-comsumer-order80 修改即可
- 需要修改pom,在pom中引入zipkin的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
- 修改application.yml 添加对于zipkin的支持
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
# 采样频率介于0到1之间,1则表示全部采集
probability: 1
- 在controller中添加如下代码去调用服务提供者
@GetMapping("/consumer/payment/zipkin")
public String pyamentZipkin(){
return restTemplate.getForObject(PAYMENT_URL+"/payment/zipkin", String.class);
}
3.4.测试
依次启动7001、7002、8001和80,通过80去调用8001,多调用几次,浏览器访问:http://localhost/consumer/payment/zipkin
打开浏览器访问http://localhost:9411,即可看到目前监控的服务, 设置查找:
进入之后即可点击查看