一、认识链路追踪
1.1、什么是链路追踪?
分布式链路追踪(Distributed Tracing),就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。
简单点来说就是:追踪微服务的调用路径。
1.2、链路追踪的由来
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协 同产生最后的请求结果,每一个请求都会
开成一条复杂的分布式服务调用链路,链路中的任何 一环出现高延时或错误都会引导起整个请求最后的失败。
建议:在微服务中链路调用不要超过 3 次
1.3、相关术语以及名词解释
完整调用链路:
Trace:类似于树结构的 Span 集合,表示一条调用链路,存在唯一标识 。
span:表示调用链路来源,通俗的理解 span 就是一次请求信息。
简化后:可以看到每个服务节点包含spanID以及一个ParentId
1.4、分布式链路相关解决方案
1、``sleuth`:SpringCloud 提供的分布式系统中链路追踪解决方案。
2、``zipkin`:由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现。该产品结合spring-cloud-sleuth使用较为简单, 集成很方便, 但是功能较简单。
什么是zipkin?
zipkin 就是一个可视化的监控控制台,Zipkin 是 Twitter 的一个开源项目,允许开发者收集 Twitter 各个服务上的监控数据,并提供查询接口。
使用效果:该系统让开发者可通过一个 Web 前端轻松的收集和分析数据,例如用户每次请求服务的处 理时间等,可方便的监测系统中存在的瓶颈。
2、``SkyWalking`:本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件, UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。
3、cat:由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 集成方案是通过代码埋点的方式来实现监控,比如: 拦截器,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。
4、``pinpoint`:Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件, UI功能强大,接入端无代码侵入。
二、认识Sleuth +Zinkin的链路追踪解决方案
注意:SpringCloud alibaba技术栈中并没有提供自己的链路追踪技术的,我们可以采用Sleuth +Zinkin来做链路追踪解决方案。
sleuth : 链路追踪器、zipkin:链路分析器(可视化)
2.1、认识Sleuth
SpringCloud Sleuth主要功能就是在分布式系统中提供追踪解决方案。它大量借用了Google Dapper的设计, 先来了解一下Sleuth中的术语和相关概念。
相关术语:
Trace (一条完整链路–包含很多span(微服务接口))
由一组Trace Id(贯穿整个链路)相同的Span串联形成一个树状结构。为了实现请求跟踪,当请求到达分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的标识(即TraceId),同时在分布式系统内部流转的时候,框架始终保持传递该唯一值,直到整个请求的返回。那么我们就可以使用该唯一标识将所有的请求串联起来,形成一条完整的请求链路。
Span
代表了一组基本的工作单元。为了统计各处理单元的延迟,当请求到达各个服务组件的时候,也通过一个唯一标识(SpanId)来标记
它的开始、具体过程和结束。通过SpanId的开始和结束时间戳,就能统计该span的调用时间,除此之外,我们还可以获取如事件的
名称。请求信息等元数据。
Annotation:
用它记录一段时间内的事件,内部使用的重要注释:
cs(Client Send)客户端发出请求,开始一个请求的生命
sr(Server Received)服务端接受到请求开始进行处理, sr-cs = 网络延迟(服务调用的时间)
ss(Server Send)服务端处理完毕准备发送到客户端,ss - sr = 服务器上的请求处理时间
cr(Client Reveived)客户端接受到服务端的响应,请求结束。 cr - sr = 请求的总时间
2.2、认识ZipKin
2.2.1、介绍ZipKin
Zipkin:是 Twitter 的一个开源项目,它基于Google Dapper实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储展现、查找和我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的REST API接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源,除了面向开发的 API 接口之外,它也提供了方便的UI组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。
Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。
上图展示了 Zipkin 的基础架构,它主要由 4 个核心组件构成:
Collector:收集器组件,它主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为Zipkin 内部处理的 Span 格式,以支持后续的存储、分析、展示等功能。
Storage:存储组件,它主要对处理收集器接收到的跟踪信息,默认会将这些信息存储在内存中,我们也可以修改此存储策略,通过使用其他存储组件将跟踪信息存储到数据库中。
RESTful API:API 组件,它主要用来提供外部访问接口。比如给客户端展示跟踪信息,或是外接系统访问以实现监控等。
Web UI:UI 组件,基于 API 组件实现的上层应用。通过 UI 组件用户可以方便而有直观地查询和分析跟踪信息。
Zipkin分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用。客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端。
2.2.2、安装ZipKin服务端
官网下载:https://zipkin.io/pages/quickstart.html
此时就获取到了对应的服务端jar包
jar包我整理好了(阿里云盘链接直接下载):https://www.aliyundrive.com/s/FitBEZU8h1o
三、实战案例:快速使用链路追踪组件Sleuth+Zipkin
spring-cloud-sleuth文档
3.1、启动zipkin服务端
我们根据2.2.2中地址来下载zipkin服务端的jar包,然后执行命令去启动:
java -jar zipkin-server-2.12.9-exec.jar
启动成功后效果:
我们可以访问其管理系统地址:http://127.0.0.1:9411/zipkin/
3.2、项目集成链路追踪sleuth
我们这里不单独创建分布式项目了,直接使用06章节中feign工程实例案例中的两个服务来进行集成。
1、添加sleuth的启动器依赖。
由于下面的order-center服务以及user-center服务都依赖common-api,所以我们直接在common.api中添加链路追踪依赖:
<!-- 链路追踪 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
2、对两个微服务来添加配置项
spring: application: name: order-service # zipkin的服务器地址 zipkin: base-url: http://localhost:9411 # sleuth配置 sleuth: sampler: # 配置1最耗时间 probability: 1 #配置采样率 默认的采样比例为: 0.1,即 10%,所设置的值介于 0 到 1 之间,1 则表示全部采集 rate: 10 #为了使用速率限制采样器,选择每秒间隔接受的trace量,最小数字为0,最大值为2,147,483,647(最大int) 默认为10。
此时我们就已经集成完毕了,之后各个服务之间进行调用时就会对其中的服务进行链路采集,我们可以在zipkin提供的管理页面来进行查看。
3.3、测试:启动服务,查看链路追踪的效果
启动一个注册中心,两个服务,其中user服务又调用order服务:
其中前者cf8f8ee5a46af0e7是TraceId, 后者684db3f642840b3c是SpanId,依次调用有一个全局的TraceId,将调用链路串起来。仔细分析每个微服务的日志,不难看出请求的具体过程。查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过Zipkin可以将日志聚合,并进行可视化展示和全文检索。
我们来尝试在浏览器中访问用户服务:http://localhost:8082/user/order/123,在这个请求中user服务就会去调用
接着我们来访问链路追踪管理页面:http://127.0.0.1:9411/zipkin/
点击查找按钮,即可出现其中的服务调用记录:
点击第一个记录,即可查看该条链路中各个服务之间的耗时:
点击依赖,我们可以看到当前服务与服务之间的一个依赖: