大家好,我是冰河~~
一不小心《SpringCloud Alibaba实战》专栏都更新到第16章了,再不上车就跟不上了,小伙伴们快跟上啊!
注意:本项目完整源码加入 冰河技术 知识星球即可获取,文末有入场方式。
在《SpringCloud Alibaba实战》专栏前面的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。也基于阿里开源的Sentinel实现了服务的限流与容错,并详细介绍了Sentinel的核心技术与配置规则。
冰河技术
分享各种编程语言、开发技术、分布式与微服务架构、分布式数据库、分布式事务、云原生、大数据与云计算技术和渗透技术。另外,还会分享各种面试题和面试技巧。
简单介绍了服务网关,并对SpringCloud Gateway的核心架构进行了简要说明,也在项目中整合了SpringCloud Gateway网关实现了通过网关访问后端微服务,同时,也基于SpringCloud Gateway整合Sentinel实现了网关的限流功能,详细介绍了SpringCloud Gateway网关的核心技术。
在链路追踪章节,我们开始简单介绍了分布式链路追踪技术与解决方案。
今天,正式进入链路追踪章节,本章,就正式在项目中整合Sleuth实现链路追踪。
本章总览
Sleuth概述
Sleuth是SpringCloud中提供的一个分布式链路追踪组件,在设计上大量参考并借用了Google Dapper的设计。
Span简介
Span在Sleuth中代表一组基本的工作单元,当请求到达各个微服务时,Sleuth会通过一个唯一的标识,也就是SpanId来标记开始通过这个微服务,在当前微服务中执行的具体过程和执行结束。
此时,通过SpanId标记的开始时间戳和结束时间戳,就能够统计到当前Span的调用时间,也就是当前微服务的执行时间。另外,也可以用过Span获取到事件的名称,请求的信息等数据。
总结:远程调用和Span是一对一的关系,是分布式链路追踪中最基本的工作单元,每次发送一个远程调用服务就会产生一个 Span。Span Id 是一个 64 位的唯一 ID,通过计算 Span 的开始和结束时间,就可以统计每个服务调用所耗费的时间。
Trace简介
Trace的粒度比Span的粒度大,Trace主要是由具有一组相同的Trace ID的Span组成的,从请求进入分布式系统入口经过调用各个微服务直到返回的整个过程,都是一个Trace。
也就是说,当请求到达分布式系统的入口时,Sleuth会为请求创建一个唯一标识,这个唯一标识就是Trace Id,不管这个请求在分布式系统中如何流转,也不管这个请求在分布式系统中调用了多少个微服务,这个Trace Id都是不变的,直到整个请求返回。
总结:一个 Trace 可以对应多个 Span,Trace和Span是一对多的关系。Trace Id是一个64 位的唯一ID。Trace Id可以将进入分布式系统入口经过调用各个微服务,再到返回的整个过程的请求串联起来,内部每通过一次微服务时,都会生成一个新的SpanId。Trace串联了整个请求链路,而Span在请求链路中区分了每个微服务。
Annotation简介
Annotation记录了一段时间内的事件,内部使用的重要注解如下所示。
- cs(Client Send)客户端发出请求,标记整个请求的开始时间。
- sr(Server Received)服务端收到请求开始进行处理,通过sr与cs可以计算网络的延迟时间,例如:sr- cs = 网络延迟(服务调用的时间)。
- ss(Server Send)服务端处理完毕准备将结果返回给客户端, 通过ss与sr可以计算服务器上的请求处理时间,例如:ss - sr = 服务器上的请求处理时间。
- cr(Client Reveived)客户端收到服务端的响应,请求结束。通过cr与cs可以计算请求的总时间,例如:cr - cs = 请求的总时间。
总结:链路追踪系统内部定义了少量核心注解,用来定义一个请求的开始和结束,通过这些注解,我们可以计算出请求的每个阶段的时间。需要注解的是,这里说的请求,是在系统内部流转的请求,而不是从浏览器、APP、H5、小程序等发出的请求。
项目整合Sleuth
Sleuth提供了分布式链路追踪能力,如果需要使用Sleuth的链路追踪功能,需要在项目中集成Sleuth。
最简使用
(1)在每个微服务(用户微服务shop-user、商品微服务shop-product、订单微服务shop-order、网关服务shop-gateway)下的pom.xml文件中添加如下Sleuth的依赖。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
(2)将项目的application.yml文件备份成application-pre-filter.yml,并将application.yml文件的内容替换为application-sentinel.yml文件的内容,这一步是为了让整个项目集成Sentinel、SpringCloud Gateway和Nacos。application.yml替换后的文件内容如下所示。
server: port: 10002 spring: application: name: server-gateway cloud: nacos: discovery: server-addr: 127.0.0.1:8848 sentinel: transport: port: 7777 dashboard: 127.0.0.1:8888 web-context-unify: false eager: true gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "*" allowedMethods: "*" allowCredentials: true allowedHeaders: "*" discovery: locator: enabled: true route-id-prefix: gateway-
(3)分别启动Nacos、Sentinel、用户微服务shop-user,商品微服务shop-product,订单微服务shop-order和网关服务shop-gateway,在浏览器中输入链接localhost:10001/server-order/order/submit_order?userId=1001&productId=1001&count=1
,如下所示。
(4)分别查看用户微服务shop-user,商品微服务shop-product,订单微服务shop-order和网关服务shop-gateway的控制台输出,每个服务的控制台都输出了如下格式所示的信息。
[微服务名称,TraceID,SpanID,是否将结果输出到第三方平台]
具体如下所示。
- 用户微服务shop-user
[server-user,03fef3d312450828,76b298dba54ec579,true]
- 商品微服务shop-product
[server-product,03fef3d312450828,41ac8836d2df4eec,true] [server-product,03fef3d312450828,6b7b3662d63372bf,true]
- 订单微服务shop-order
[server-order,03fef3d312450828,cbd935d57cae84f9,true]
- 网关服务shop-gateway
[server-gateway,03fef3d312450828,03fef3d312450828,true]
可以看到,每个服务都打印出了链路追踪的日志信息,说明引入Sleuth的依赖后,就可以在命令行查看链路追踪情况。
抽样采集数据
Sleuth支持抽样采集数据。尤其是在高并发场景下,如果采集所有的数据,那么采集的数据量就太大了,非常耗费系统的性能。通常的做法是可以减少一部分数据量,特别是对于采用Http方式去发送采集数据,能够提升很大的性能。
Sleuth可以采用如下方式配置抽样采集数据。
spring: sleuth: sampler: probability: 1.0