一、应用场景
随着业务的发展,系统规模会变得越来越大,各微服务间的调用关系会变得越来越复杂。通常一个由客户端发起的请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一条复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟过高或错误的时候都有可能引起请求最后的失败。这时候,对于每个请求,全链路调用的跟踪就变得越来越重要。通过实现请求调用的跟踪,可以帮助我们快速发现错误根源以及监控分析每条请求链路上的性能瓶颈等。
针对以上问题,Spring Cloud Sleuth 提供了一套完整的解决方案。
二、Spring Cloud Sleuth相关原理解析
(一)添加依赖
<!-- 依赖 spring cloud sleuth -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
(二)实现跟踪
在我们发起一个请求之后,服务开始互相调用,在调用时,会打印出相应的日志,诸如下面的日志:
2018-12-10 10:45:34.376 INFO [user-service-client,42951db6d8324311,42951db6d8324311,false] 9340 --- [nio-8080-exec-1]
从上面的日志中,我们可以看到形如 [user-service-client,42951db6d8324311,42951db6d8324311,false]
的日志信息,而这些元素正是实现分布式服务跟踪的重要组成部分,每个值的含义如下:
- 第一个值:
user-service-client
,它记录了应用的名称,也就是application.properties
中spring.application.name
参数配置的属性。 - 第二个值:42951db6d8324311,Spring Cloud Sleuth 生成的一个ID,称为 Trace ID,它用来标识一条请求链路。一条请求链路包含一个 Trace ID,多个 Span ID.
- 第三个值:42951db6d8324311,Spring Cloud Sleuth 生成的另外一个ID,称为 Span ID,他表示一个基本的工作单元,比如发送一个 HTTP 请求。
- 第四个值:false,表示是否要将该信息输出到 Zipkin 等服务中来收集和展示。
(三)跟踪原理
分布式系统中的服务跟踪在理论上并不复杂,它主要包括下面两个关键点:
- 为了实现请求跟踪,当请求发布到分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的跟踪标识,同时分布式系统内部流转的时候,框架始终传递该唯一标识,直到返回给请求方为止,这个唯一标识就是上面的 Trace ID。通过 Trace ID 的记录,我们就能将所有请求过程的日志关联起来。
- 为了统计各处理单元的时间延迟,当请求到达各个服务组件时,或是处理逻辑到达某个状态时,他通过一个唯一标识来标记他的开始、具体过程以及结束,该标识就是前文提到的 Span ID。对于每个 Span 来说,他必须有开始和结束两个节点,通过记录开始 Span 和 结束 Span 的时间戳,就能统计出该 Span 的时间延迟,除了时间戳记录以外,它还可以包含一些其他元数据,比如事件名称、请求信息等。
三、整合 Zipkin
(一)Zipkin 服务器
值得注意的是:
Spring Boot 2.0之后,使用EnableZipkinServer创建自定义的zipkin服务器已经被废弃,将无法启动.ZipkinServer 由官方提供jar包。我们只需要到官网下载即可。地址:https://zipkin.io/pages/quickstart , 找到latest release 进行下载。
若还是下载失败,则需要手动在 https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server 网页上下载最新版本的 zipkin-server-***.jar文件!
在下载完毕以后,我们使用 java -jar zipkin.jar
启动 zipkin 服务器,同时为了保证能被外部程序访问,需要开启 zipkin 服务器默认端口 9411,如下:
/sbin/iptables -I INPUT -p tcp --dport 9411 -j ACCEPT&&/etc/init.d/iptables save&&service iptables restart&&/etc/init.d/iptables status
然后,访问http://192.168.10.130:9411/,出现 zipkin 管理界面:
(二)整合 Zipkin 客户端
改造 user-service-client
1、添加 Maven 依赖
<!-- 整合 zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
2、连接 Zipkin 服务器
application.properties
#连接 zipkin 服务器(http://${zipkin.server.host}:${zipkin.server.port})
zipkin.server.host=192.168.10.130
zipkin.server.port=9411
spring.zipkin.base-url=http://${zipkin.server.host}:${zipkin.server.port}
#zipkin采集率 0.1(默认)表示 10%采集率(丢失率极高),开发测试设为1.0,生产0.1
spring.sleuth.sampler.probability=1.0
改造 user-service-provider
1、添加 Maven 依赖
<!-- 整合 zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
2、连接 Zipkin 服务器
application.properties
#连接 zipkin 服务器(http://${zipkin.server.host}:${zipkin.server.port})
zipkin.server.host=192.168.10.130
zipkin.server.port=9411
spring.zipkin.base-url=http://${zipkin.server.host}:${zipkin.server.port}
#zipkin采集率 0.1(默认)表示 10%采集率(丢失率极高),开发测试设为1.0,生产0.1
spring.sleuth.sampler.probability=1.0
通过以上步骤,即可在 zipkin 管理界面查看请求链路信息。
注意:spring boot2.0 以后,
spring-cloud-sleuth-stream
不再推荐使用,若有需要使用消息中间件(诸如 kafka等),则可以参考 https://github.com/mercyblitz/segmentfault-lessons/tree/master/spring-cloud/lesson-15 页面中的改造Zipkin 服务器:使用 Stream 方式订阅