链路追踪(⼀)-分布式链路追踪系统的介绍
分布式链路追踪系统的介绍
⼀、分布式链路追踪可以做什么?
1.1简单集架构&微服务架构
先来看下最简单的⽹站集架构图:
图1
在这个图⾥,存在从1~n个服务器,通过负载均衡器SLB进⾏请求分发,在每个服务器⾥,都做同⼀件事情。
现在来看下这个系统的具体业务逻辑(就是图1中每台服务器执⾏的逻辑,这⾥是假设其中⼀个业务接⼝的处理,真实系统中可能存在n多业务接⼝):
图2
图2是对系统中某⼀个接⼝(API)的逻辑做了描述,假设处理流程就是请求⼀次Redis服务,然后做下处理,然后再请求下Memecached 服务,在做下业务处理,后续可能还有其他各种业务逻辑,我们统称为逻辑块。
现在假设这个接⼝存在性能问题,那么对应开发负责⼈排查是⽐较容易的,因为服务器只执⾏⼀套逻辑,瓶颈点⼀定发⽣在当前接⼝对应代码⾥的某个点,那么就接⼝对应的负责⼈去排查优化即可。
但是当业务发展到⼀定的程度,⽐如上述单系统逻辑越来越复杂(业务接⼝越来越多,逻辑越来越复杂),就会造成很多我们不愿意看到的问题发⽣:
①每⼀次微⼩的改动都需要整体⾛⼀次打包、发版的流程,对测试也是种负担,因为n多个⼈如果同时开发不同的功能,这时候就会对测试和发布流程造成很⼤的困扰。
②如果因为做某次活动,某⼀个接⼝可能引⼊⼤量请求,需要紧急扩容,那么只能对整体扩容(因为该接⼝与其他接⼝都处于同⼀个系统中)。
③系统各模块⾼度耦合,不适合多⼈开发和维护。
简单集带来的问题会随着系统复杂度的提升,维护成本变得越来越⼤,基于此,便有了微服务架构
分布式和微服务的关系(微服务是⼀种架构思想,简单来说就是将复杂庞⼤耦合度⾼的系统按照功能特性拆分成⼀个个独⽴的系统,通过⽹络互相通信,这种架构可以借助RPC框架实现拆分,当然,熟悉的HTTP也可以做到,但是限于上层HTTP协议,性能可能没有普通RPC框架⾼,⽐如grpc上层协议基于HTTP2,这个协议相⽐
HTTP1,⽀持流标记,因此可以在⼀个长连接上做N多请求的并发处理,属于全双⼯⽹络通信,这点放到HTTP1就很难做到,这⾥不再赘述)。
结合图2,我们来简单按照业务划分⼀下服务,可以将A代码块⾥的逻辑抽象成A服务,将B代码块⾥的逻辑抽象成B服务,当然还有可能有其他n多细化的服务,⽹关层API(负责聚合信息以及业务处理的模块,对应上⾯简单集⾥的具体接⼝),服务注册与发现、SLB等。
下⾯再来看⼀下被拆分后的架构图:
图3
这张图是⼀个很简单的微服务化的架构图,图中虚线部分都是在各服务启动时或者运⾏期发⽣的调⽤,负责注册与发现(如zookeeper、Eurake等都可以作服务注册与发现,这⾥不再细说,只关注实线部分即可)。
这种架构很好的解决了普通集架构带来的问题(参考上述①、②、③),微服务架构的好处:
①降低了系统(逻辑块)间的耦合度,可以独⽴开发、独⽴部署和测试,系统间的边界明确,可以细分相关负责⼈,开发效率⼤⼤提升。
②如果因为做某次活动,某⼀个接⼝可能引⼊⼤量请求,需要紧急扩容,那么只需要将该接⼝涉及到的服务进⾏扩容即可,⽽不是像之前那样整体扩容,降低了维护成本(某种意义上的降低,维护⼈员要⾜够多,每个⼈去负责⾃⼰的⼩模块,如果⼀个公司只有⼀个维护⼈员,微服务反⽽是在加重维护⼈员的⼯作:)。
③提⾼了系统(逻辑块)的复⽤性,⽐如上⾯的服务A做⾃⼰的事情,万⼀以后有个API仍然需要A逻辑块,那么该API只需要再次调⽤A服务即可(实际应⽤当中的例⼦:⽤户服务)。
④服务化以后,每个服务甚⾄可以⽤不同的语⾔来实现(⽀持跨语⾔的RPC框架很多,⽐如grpc),
⼀个公司⼤了以后,可能存在语⾔差异,有的组使⽤JAVA,有的组⽤Go,通过服务化的⽅式,来将两个不同语⾔的系统互联。
上⾯简单介绍了普通集架构和微服务架构,同样的,微服务化也意味着系统调⽤的复杂化,有可能⼀次API的调⽤对应⼤批量的服务调⽤,服务⽅⾃⼰⼜有⼀堆服务调⽤,那么针对这种问题,我们来模拟⼀次复杂的API调⽤(注册与发现服务已隐藏),如图4所⽰:
图4
这是模拟了⼀次微服务架构中⽐较复杂的系统调⽤。
那么现在如果这个较复杂的链路调⽤上的其中⼀环发⽣了性能瓶颈,拖慢了整个API的调⽤,⽐如图中的“慢”标识,现在我们再来模拟⼀下这个性能问题的排查过程:
负责API编写的同学发现API的响应时间总是达不到预期的速度,⾃⼰debug发现导致性能问题的原因是服务C,于是到了服务C的负责⼈⼩C,⼩C紧接着排查,发现原来是服务D的调⽤过慢,于是⼜跑去⼩D,⼩D收到⼩C的反馈,然后去查⾃⼰的服务,发现⾃⼰调⽤的服务E响应缓慢,于是⼩D⼜跑去⼩E,⼩E紧接着排查,发现原来是⾃⼰这⾥调⽤的Redis_02服务有问题,然后⾃⼰排查,如果不是⾃⼰调⽤⽅式有问题,接下来还可能去联系对应的Redis_02相关维护⼈员帮助检查瓶颈点。
对⽐简单集⽅式中的单系统性能问题排查,微服务针对此类问题的排查简直是⼀场噩梦,这其中涉及到的⼈跟瓶颈节点的深度成正⽐,因为任何⼀个环节都有可能存在性能问题,⽽拖慢整个进度的根源未知,那么有没有⼀种⼯具可以完成跨服务跨系统的去跟踪这次的调⽤链路呢?
1.2分布式链路追踪
结合上⾯的问题,分布式链路追踪系统就诞⽣了,先来看下Google的这篇⽂章:,可以对分布式链路
追踪系统有个系统的认识。
单纯的理解链路追踪,就是指⼀次任务的开始到结束,期间调⽤的所有系统及耗时(时间跨度)都可以完整记录下来,⽐如上⾯图4的例⼦,假设总耗时100ms,存在瓶颈链路C-->D-->E-->Redis02,如果链路追踪系统做好了,链路数据有了,借助前端解析和渲染⼯具,可以达到下图中的效果:
图5
可以看到从API的调⽤开始到每个涉及到的系统调⽤以及系统内部的调⽤链路和时间跨度被直观的展⽰出来了,通过上图,可以看到时间跨度最长的就是Redis_02,该服务的调⽤间接拖慢了E服务、D服务、C服务的响应,最后由C服务直接导致API整体响应缓慢,通过这个图,就可以直接到对应的责任⼈去排查对应的问题,⽽不是像之前那样⼀⼈。
⼆、分布式链路追踪系统的组成
类似很多监控系统,该系统也分为基础数据采集+数据存储+前端展⽰⼏个部分,来看下⼀个分布式链路系统的基本结构:
图6
上图⽐较粗略的展⽰了⼀个完整的链路追踪系统的结构,本篇⽂章不会介绍具体的链路追踪系统的实现,可以先简单将该系统理解为接收
+存储链路数据的作⽤,前端也⼀样,可以先简单理解为请求链路系统API,API内部负责读取db,并将数据封装成前端需要的格式,前端负责绘制图5中的页⾯即可(只要数据结构约定好,对于专业的前端⼯程师做出图5的效果是很容易的,当然⽹上也有现成的前端⼯具)。
本篇⽂章主要介绍链路追踪究竟是什么,可以解决什么问题,下⼀篇将会详细介绍“链路数据采集SDK”,因为这⼀部分是跟业务组件开发⼈员直接挂钩的,下⼀篇会说明链路追踪的数据结构、如何做到链路数据的采集和上报、如何做到跨服务的链路追踪。
开始前可以先了解⼀个标准:
这⾥⾯讲了两个很重要的概念:Tracer和Span,⼀个Tracer认为是⼀次完整的链路,内部包含n多个Span,Span表⽰具体的⼀次调⽤,图5中就是⼀次完整的调⽤链路,⾥⾯每个耗时条都是⼀个Span,Tracer和Span存在⼀对多的关系(看到这⾥,图6中的链路追踪API的实现可以认为是根据Tracer的id聚合⼀批存在⽗⼦关系的Span封装成定义好的数据结构传给前端进⾏渲染的),根据图5,可以知道Span与Span之间⼜存在⽗⼦关系。
具体的实现⽅案和实现⽅法,下⼀篇会详细介绍~下⼀篇会围绕着图5进⾏展开。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。