32、Spring Cloud 服务跟踪总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了32、Spring Cloud 服务跟踪总结相关的知识,希望对你有一定的参考价值。
参考技术A
上两篇讲解了zipkin,这篇总结一下。其实Spring Cloud实施分布式跟踪解决方案所用的技术不仅仅是zipkin。在spring官网:
http://spring.io/projects/spring-cloud-sleuth
有这么一段话:
翻译过来:
Spring Cloud Sleuth是Spring Cloud实施分布式跟踪解决方案,大量借用Dapper,Zipkin和HTrace。 对于大多数用户来说,侦探应该是隐形的,并且所有与外部系统的交互都应该自动进行检测。 您可以简单地在日志中捕获数据,也可以将数据发送到远程收集器服务。
Spring Cloud Sleuth借用了Dapper的术语:
跨度(Span):基本的工作单位。例如,发送一个RPC是一个新的跨度,就像向RPC发送响应一样。跨度由跨度的唯一64位ID和跨度所包含的另一个 64位ID标识。Spans还具有其他数据,例如描述,时间戳事件,键值注释(标记),导致它们的跨度的ID以及进程ID(通常为IP地址)。跨度启动和停止,并跟踪他们的时间信息。一旦你创建了一个跨度,你必须在将来某个时候停止它。开始追踪的初始跨度被称为 root span。该跨度的span id的值等于trace id。
痕迹(Trace):一组形成树状结构的跨度。例如,如果您正在运行分布式大数据存储,则跟踪可能由放入请求组成。
标注(Annotation):用于及时记录事件的存在。用于定义请求开始和结束的一些核心注释是:
cs - 客户端发送 - 客户端发出请求。这个注释描述了跨度的开始。
sr - 服务器已收到 - 服务器端收到请求并开始处理。如果从这个时间戳中减去cs时间戳,将会收到网络延迟。
ss - 服务器发送 - 在请求处理完成时(当响应被发送回客户端时)注释。如果从这个时间戳中减去sr时间戳,将会收到服务器端处理请求所需的时间。
cr - 客户端收到 - 表示跨度结束。客户端已经成功接收到服务器端的响应。如果从这个时间戳中减去cs时间戳,那么将会收到客户端接收服务器响应所需的全部时间。
Span 和 Trace 在系统中与 Zipkin Annotation 一起显示的可视化示例:
(https://github.com/spring-cloud/spring-cloud-sleuth)
1、依赖说明
从中央仓库https://mvnrepository.com可以查询到以下与zipkin和sleuth相关的jar引用:spring-cloud-starter-zipkin、spring-cloud-starter-sleuth、spring-cloud-sleuth-zipkin,他们只有有什么关系呢?
从pom.xml的引用关系可以看到spring-cloud-starter-zipkin包含了spring-cloud-starter-sleuth和spring-cloud-sleuth-zipkin,就是所引入spring-cloud-starter-zipkin就等于引用了spring-cloud-starter-sleuth和spring-cloud-sleuth-zipkin
2、配置说明
Zipkin和Sleuth配置类分别是:
Zipkin: org.springframework.cloud.sleuth.zipkin2.ZipkinProperties
Sleuth: org.springframework.cloud.sleuth.autoconfig.SleuthProperties
从这两个类就可以知道Zipkin和Sleuth分别有哪些配置项
3、 分布式服务跟踪系统原理
分布式服务跟踪系统,主要有三部分:数据收集、数据存储和数据展示。根据系统大小不同,每一部分的结构又有一定变化。譬如对于大规模分布式系统,数据存储可分为实时数据和全量数据两部分,实时数据用于故障排查(trouble shooting),全量数据用于系统优化;数据收集除了支持平台无关和开发语言无关系统的数据收集,还包括异步数据收集(需要跟踪队列中的消息,保证调用的连贯性),以及确保更小的侵入性;数据展示又涉及到数据挖掘和分析。虽然每一部分都可能变得很复杂,但基本原理都类似。
阿里云的一些服务可以类比,比如你需要收集一台云主机的IO情况,CPU使用率、磁盘使用情况等;就需要在我们的云主机安装一个代理agent(类比Zipkin Client),这个代理agent的作用就是收集当前主机的数据,然后上送到管理控制台(类比Zipkin Server)
(56)java Spring Cloud+Spring boot+mybatis企业快速开发架构之Spring Cloud整合Zipkin进行服务跟踪
Zipkin 是 Twitter 的一个开源项目,是一个致力于收集所有服务的监控数据的分布式跟踪系统,它提供了收集数据和查询数据两大接口服务。有了 Zipkin 我们就可以很直观地对调用链进行查看,并且可以很方便地看出服务之间的调用关系以及调用耗费的时间。
需要框架源码的朋友可以看我个人简介联系我。 鸿鹄分布式云架构源码
Zipkin 数据收集服务
部署 Zipkin 需要先下载已经编译好了的 jar 包,然后 java–jar 启动即可。
启动后访问 http://localhost:9411/zipkin/ 就可以看到管理页面了,如图 1 所示。
需要在项目中添加依赖,具体代码如下所示。
1
2
3
4
|
<dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-zipkin</artifactid> </dependency> |
在属性文件中可以配置 Zipkin 的地址,默认是 http://127.0.0.1:9411,这样才能将跟踪的数据发送到执行的收集服务中。
然后我们启动之前的服务、访问接口,就可以看到数据已经能够在 Zipkin 的 Web 页面中了,如图 2 和图 3 所示。
停掉被访问的服务,模拟一下异常情况,通过 Zipkin 的 UI 可以快速发现请求异常的信息,如图 4 所示。
抽样采集数据
在实际使用中可能调用了 10 次接口,但是 Zipkin 中只有一条数据,这是因为收集信息是有一定比例的,这并不是 bug。Zipkin 中的数据条数与调用接口次数默认比例是 0.1,当然我们也可以通过配置来修改这个比例值:
#zipkin 抽样比例
spring.sleuth.sampler.probability=1.0
之所以有这样的一个配置,是因为在高并发下,如果所有数据都采集,那这个数据量就太大了,采用抽样的做法可以减少一部分数据量,特别是对于 Http 方式去发送采集数据,对性能有很大的影响。
异步任务线程池定义
Sleuth 对异步任务也是支持的,我们用 @Async 开启一个异步任务后,Sleuth 会为这个调用新创建一个 Span。
如果你自定义了异步任务的线程池,会导致无法新创建一个 Span,这就需要使用 Sleuth 提供的 LazyTraceExecutor 来包装下。代码如下所示。@Configuration
如果直接 return executor 就不会新建 Span,也就不会有 save-log 这个 Span。如图 6 所示。
我们在响应头中设置了请求 ID,可以通过查看请求的响应信息来验证是否设置成功,如图 7 所示。
自定义标记是一个非常实用的功能,可以将请求对应的用户信息标记上去,排查问题时非常有帮助。
监控本地方法
异步执行和远程调用都会新开启一个 Span,如果我们想监控本地的方法耗时时间,可以采用埋点的方式监控本地方法,也就是开启一个新的 Span。代码如下所示。
通过手动埋点的方式可以创建新的 Span,在 Zipkin 的 UI 中也可以看到这个本地方法执行所消耗的时间,可以看到 savelog2 花费了 2 秒的时间,如图 9 所示。
过滤不想跟踪的请求
对于某些请求不想开启跟踪,可以通过配置 HttpSampler 来过滤掉,比如 swagger 这些请求等。代码如下所示。
核心在 trySample 方法中,只要不想跟踪的 URL 直接返回 false 就可以过滤。规则可以自定,笔者用了 SkipPatternProvider 来过滤,SkipPatternProvider 中的 skipPattern 配置了很多过滤规则。
1
2
3
|
/api-docs.*|/autoconfig|/configprops|/dump|/health|/info|/metrics.*| /mappings|/trace|/swagger.*|.*\\.png|.*\\.css|.*\\.js|.*\\.html|/favicon.ico| /hystrix.stream|/application/.*|/actuator.*|/cloudfoundryapplication |
用RabbitMq代替Http发送调用链数据
虽然有基于采样的收集方式,但是数据的发送采用 Http 还是对性能有影响。如果 Zipkin 的服务端重启或者挂掉了,那么将丢失部分采集数据。为了解决这些问题,我们将集成 RabbitMq 来发送采集数据,利用消息队列来提高发送性能,保证数据不丢失。
在服务中增加 RabbitMq 的依赖:
1
2
3
4
|
<dependency> <groupid>org.springframework.amqp</groupid> <artifactid>spring-rabbit</artifactid> </dependency> |
然后在属性文件中增加 RabbitMq 的连接配置:
到这里,集成就已经完成了,记得去掉之前配置的 spring.zipkin.base-url。因为我们现在利用 RabbitMq 来发送数据了,所以这个配置就不需要了。
数据发送方已经采用 RabbitMq 来发送调用链数据,但是 Zipkin 服务并不知道 RabbitMq 的信息,所以我们在启动 Zipkin 服务的时候需要指定 RabbitMq 的信息。
1java -DRABBIT_ADDRESSES=
192.168
.
10.124
:
5672
- DRABBIT_USER=zhangsan -DRABBIT_PASSWORD=
123456
-jar zipkin.jar
用Elasticsearch存储调用链数据
目前我们收集的数据都是存在 Zipkin 服务的内存中,服务一重启这些数据就没了,我们需要将这些数据持久化。我们可以将其存储在MySQL 中,实际使用中数据量可能会比较大,所以 MySQL 并不是一种很好的选择,可以选择用 Elasticsearch 来存储数据,Elasticsearch 在搜索方面有先天的优势。
启动 Zipkin 的时候指定存储类型为 ES,指定 ES 的 URL 信息:
重启服务,然后收集一些数据,我们可以通过两种方式来验证数据是否存储到了 Elasticsearch 中。
可以重启 Zipkin 服务,然后看看数据是否还存在,如果存在则证明数据已经是持久化了。
可以通过查看 Elasticsearch 中的数据来确认数据有没有存储成功,访问 Elasticsearch 的地址查看当前所有的索引信息:http://localhost:9200/_cat/indices。
可以看到当前节点下面有哪些索引,如果看到有以 zipkin 开头的就说明索引创建了,接着直接查询这个索引下是否有数据即可认证是否存储成功,访问 http://localhost:9200/索引名称/_search。
以上是关于32、Spring Cloud 服务跟踪总结的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud 与微服务学习总结(15)—— Spring Cloud 2021.0.1 发布