分布式服务跟踪实现方法与流程

文档序号:12182440
本发明涉及一种分布式系统的跟踪处理方法,尤其是涉及一种分布式服务跟踪实现方法。
背景技术
::如今互联网服务通常都是用复杂的、大规模分布式集群来实现的,互联网应用构建在不同的软件模块集上。这些软件模块,有可能是由不同的团队开发、也有可能使用不同的编程语言来实现、还有可能分别部署在不同的服务器上,横跨多个不同的数据中心。因此,就需要有一些可以帮助理解系统行为、用于分析系统性能问题的工具。比如在搜索系统中,用户的一个请求在系统中会经过多个子系统的处理,而且这些处理是发生在不同机器甚至是不同集群上的,当请求处理发生异常时,需要快速发现问题,并准确定位到是哪个环节出了问题,这是非常重要的。为了解决这样的问题,谷歌开发了分布式跟踪系统Dapper并发布了一篇论文《Dapper,aLarge-ScaleDistributedSystemsTracingInfrastructure》(《Dapper,大型分布式系统跟踪系统的基础设施》)来阐述其核心理论。目前可查的分布式跟踪系统的实现,其基本理论都源于谷歌的这篇论文。但是Dapper只是为解决请求调用这一问题提出了理论模型,并没有提供具体的实现。本发明的分布式跟踪系统是在博采众家之长的基础上提供了完整的分布式系统的跟踪解决方案,更符合现有SOA(面向服务的体系结构)系统架构需求。可以做到接入透明,对业务的性能影响微乎其微,实时跟踪,同时本发明的分布式跟踪系统提供的实时预警功能保证在系统出现异常甚至宕机的情况下可以及时通知预警,保证系统的稳定性和高可用性。技术实现要素:本发明提供了一种分布式服务跟踪实现方法,解决了分布式系统中进程调用过程中产生问题时的查询跟踪问题,其技术方案如下所述:一种分布式服务跟踪实现方法,包括日志采样模块、日志收集模块、日志存储模块、统计报表模块、前端模块,所述日志采样模块利用拦截器拦截技术或面向切面编程技术拦截分布式调用链中的进程行为,所述日志收集模块定期实时读取文件,并将有用的日志信息发送到日志存储模块,所述统计报表模块定期进行日志统计,前端模块提供用户交互界面;整体架构称为Cicada;对于请求发起进程的设为客户端,服务提供进程的设为服务端,同一次请求的所有相关调用的情况称作分布式调用链,记为Trace,每个分布式调用链拥有一个全局唯一的ID来标识,其中所述服务端调用其他进程时成为该调用中的的客户端,该跨进程的一次调用记为Span;在客户端的前端请求到达服务器时,应用容器在执行实际业务处理之前,会先执行Cicada的埋点逻辑,埋点逻辑为这个前端请求分配一个全局唯一的调用链ID,称为TraceId,埋点逻辑把TraceId放在一个调用上下文对象Span里面,而调用上下文对象会存储在ThreadLocal里面,ThreadLocal能够基于线程进行数据的存储和读取,能在同一次请求的多个本地处理方法间传递信息。所述Span包括客户端Span和服务端Span,一个远程调用对应两个span,多条Span形成树形结构,组合成一次Trace追踪记录,在Span中的标注点用于记录整个Span时间段内发生的事件,用特殊标注点记录用户自定义事件。所述标注点的属性包括timestamp、type、ip、port,分别表示记录行为发生时间、记录行为类型、IP地址、端口;所述特殊标注点的属性包括timestamp、type、ip、port、key、value,分别表示记录行为发生时间、记录行为类型、IP地址、端口、用户定义属性名、用户定义属性值;所述Span的属性包括traceId、Id、parentId、appName、serviceName、methodName、subSpanNum、annotations、binaryAnnotations,分别表示分布式调用唯一id、Span唯一id、Span父id、应用名、类名、方法名、子span数量、调用信息、补充信息或异常信息。在调用上下文时设置有第二种ID,称作spanId,用于区分同一个调用链下的多个网络调用的发生顺序和嵌套层次关系;对于前端收到请求,生成的spanId固定都是1,当这个前端执行业务处理需要发起RPC调用时,RPC调用客户端Dubbo会首先从当前线程ThreadLocal上面获取之前设置的调用上下文,然后,把spanId递增一个序号,并使用多级序号来表示spanId;之后,调用上下文会作为附件随这次请求一起发送到远程的Dubbo服务器,远程的Dubbo服务端收到这个请求之后,会从请求附件里取出调用上下文,并放到当前线程ThreadLocal上面;如果服务A在处理时,需要调用另一个服务,则会重复以上步骤,并将spanId递增一个序号再传过去,服务A的逻辑全部处理完毕之后,Dubbo在返回响应对象之前,会把这次调用情况以及traceId、spanId都打印到它的访问日志之中,同时,会从ThreadLocal清理掉调用上下文。当服务发生时,所述日志采样模块拦截分布式系统各组成部分的处理行为,记录行为日志并将日志通过HttpPost异步发送到日志收集模块,将收集好的日志发送到远程服务器时采用批处理和异步发送的方法,并增加了连接超时设置和传输超时设置,将超过一定时长的日志直接扔掉,同时对单位时间内抓取的日志量过多的情况进行了限流处理。所述日志收集模块分日志接收子系统和日志汇总子系统,所述日志接收子系统为nginx集群,所述nginx接收到客户端POST过来的消息数据,直接记录本地文件;所述日志汇总子系统从nginx日志中读取最新数据,记录读取进度并进行数据清洗,将异步数据存储到ElasticSearch。所述统计报表模块进行定期日志统计,统计项包括以下:avgDuration:平均响应时间;minDuration:最快响应时间;maxDuration:最慢响应时间;line95Duration:95%line最大响应时间;line999Duration:99.9%line最大响应时间;failureRate:请求失败率;提供统计结果以及Trace数据访问的RESTful接口。本发明能够透明的传递调用上下文,理解系统行为,理清后端调用关系,实现调用链跟踪,调用路径分析,帮助业务人员定位性能瓶颈,排查故障原因等;同时,需要对用户尽量透明,减少对业务代码的侵入性。附图说明图1是本发明中典型的分布式调用跟踪模型图;图2是一个浏览器请求可能触发的系统间调用以及生成spandId的关系图;图3是本发明整体架构的示意图;图4是本发明系统部署图。具体实施方式分布式系统为应用带来高可用、高性能、水平扩展等特性,同时也给应用部署、排查、监控等方面带来了复杂性。对单一进程的系统来说,涉及到用户一次请求的所有处理都在同一个进程里,请求相关的所有属性记录在本地即可,无需在多个系统之间传递,方法调用之间的先后顺序按照事件记录的时间先后顺序即可,处理起来也很容易。而对于分布式系统来说,面临的问题则要复杂很多。响应一次请求的分布式服务可能分散在不同的服务器不同的进程里,如何准确的把这些服务找出并关联起来是其面临的首要问题。同时,要准确的分析出这些服务发生的先后关系,也是一个比较棘手的问题。由于服务相关的进程分布在不同的服务器上,而服务器的时间有可能不一致(比如如后服务的服务器时间比较靠前,先服务的服务器时间比较靠后)如果采用时间进行区分的话,就可能导致分析错误。要解决此问题,必须寻求其他解决途径。上面两个问题,主要涉及到记录信息的数据结构问题,在解决了这个问题之后,又面临着一个新的问题,即信息传递问题。前面已经提到过本地调用之间、跨进程的调用之间必然存在一些关联信息,而要让这些关联信息发挥作用,必然要在所有调用之间通过某种方式共享信息。在解决了数据结构定义以及调用信息在系统之间传递的问题后,需要考虑服务信息抓取问题,即如何简单有效、低侵入甚至无侵入的获取分布式服务的处理信息。接着,要考虑系统的扩展性,用户可能想自定义一些需要采集的数据,以便跟准确的监控、分析服务运转状态。最后,要尽可能的把架构做的轻量,越是轻量级的服务,部署起来越容易,排查问题越简单,越节省成本。要实现分布式跟踪系统,首先要解决的问题是定义好跟踪模型,模型的关键又在数据结构定义。其核心内容如下:Client(客户端)和Server(服务端)在分布式系统中,请求发起进程和服务提供进程扮演的角色很像是C/S架构(经典软件架构模型,C代表Client,S代表Server)中客户端和服务端的扮演的角色。作为类比,我们称请求发起进程为Client,服务提供进程为Server。由于存在多层依赖,所以在一次分布式请求中,可能存在这样一种情况:一个进程在处理过程中,同时扮演Client和Server角色。也就是说一个进程可能是上一个Span的服务端,同时是下一个Span的客户端,比如在一次请求中进程A调用了进程B,进程B又调用了进程C。对于进程A来说,进程B的角色是Server,但是对于进程C来说进程B是Client。Trace(分布式调用链)一次分布式请求涉及到的所有调用链路。一次请求对应一个Trace,一个Trace拥有一个全局唯一的Id来标识。Span调用上下文对象,记录分布式调用相关信息,是追踪服务基本结构,表示跨进程的一次调用。一个完整的Span包含两天Span记录,一条是客户端Span,一条是服务端Span。多条Span形成树形结构,组合成一次Trace追踪记录。Annotation在span中的标注点,记录整个span时间段内发生的事件。BinaryAnnotation可以认为是特殊的Annotation,用户自定义事件。那么,Annotation类型包括下面两种:1、保留类型CSCLIENT_SEND,客户端发起请求CRCLIENT_RECIEVE,客户端收到响应SRSERVER_RECIEVE,服务端收到请求SSSERVER_SEND,服务端发送结果2、用户自定义类型Event记录普通事件Exception记录异常事件图1是一个典型的分布式调用跟踪模型图,结合下图可以帮助我们理解上面的术语。重要数据结构:类:Annotation重要属性:类说明:记录span调用的部分相关信息,主要是发生时间和ip信息。类:BinaryAnnotation重要属性:类说明:记录span调用的异常信息或用户自定义的信息。类:Span重要属性:类说明:调用上下文对象,记录分布式调用相关信息,span信息核心类,一个远程调用对应两个span,一个是客户端span,一个是服务端span。本发明的整体处理流程简单如下所述:日志采集流程:利用Filter(拦截器)拦截技术或AOP(面向切面编程)技术拦截进程行为将搜集到的数据异步批处理发送到Tengine(由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性)集群。Tengine集群收到数据后,将数据保写入本地文件日志处理流程:日志收集后处理进程定期实时读取文件,过滤掉不符合规则的或无效的日志信息,然后将有用的日志信息发送到ElasticSearch(用Java(全球通用开发语言)开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎,可以存放数据)。日志分析进程定期实时从ElasticSearch中读取日志信息并进行汇总处理,汇总处理结果存放到Mysql(关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品。)中方便查询。同时对于满足报警条件的处理,发送报警信息。日志展示Dashboard(分布式跟踪显示页面)是用于跟用户交互的前端页面。能够根据用户的指示展示不同的统计结果。本发明具体的详细处理流程如下所述:同一次请求的所有相关调用的情况,在Cicada里称作调用链。同一个时刻某一台服务器并行发起的网络调用有很多,怎么识别这个调用是属于哪个调用链的呢?可以在各个发起网络调用的中间件上下手。具体流程如下:1)TraceId生成及调用上下文信息存取在前端请求到达服务器时,应用容器在执行实际业务处理之前,会先执行Cicada的埋点逻辑(类似Filter的机制),埋点逻辑为这个前端请求分配一个全局唯一的调用链ID。这个ID在Cicada里面被称为TraceId,埋点逻辑把TraceId放在一个调用上下文对象Span里面,而调用上下文对象会存储在ThreadLocal里面。ThreadLocal技术非常关键,它可以基于线程进行数据的存储和读取,能在同一次请求的多个本地处理方法间传递信息。其中前端请求是指当用户的请求发送到服务器,Cicada的处理流程,所以这儿的提到的前端请求也可以写作用户的请求。所述应用容器是从代码部署的环境来区分的,部署在服务器环境下的叫做后段,相应的发布到用户器材上的程序叫做前端,必入浏览器、app之类。2)spanId生成细节调用上下文里还有一个ID非常重要,在Cicada里面被称作spanId。spanId用于区分同一个调用链下的多个网络调用的发生顺序和嵌套层次关系。对于前端收到请求,生成的spanId固定都是1。当这个前端执行业务处理需要发起RPC调用时,RPC调用客户端Dubbo(分布式服务框架)会首先从当前线程ThreadLocal上面获取之前Cicada设置的调用上下文。然后,把spanId递增一个序号。在Cicada里使用多级序号来表示spanId,比如前端刚接到请求之后的spanId是1,那么它第一次调用RPC服务A时,会把spanId改成1.1。之后,调用上下文会作为附件随这次请求一起发送到远程的Dubbo(一款开源的分布式服务框架)服务器。Dubbo服务端收到这个请求之后,会从请求附件里取出调用上下文,并放到当前线程ThreadLocal上面。如果服务A在处理时,需要调用另一个服务,这个时候它会重复之前提到的操作,唯一的差别就是spanId会先改成1.1.1再传过去。服务A的逻辑全部处理完毕之后,Dubbo在返回响应对象之前,会把这次调用情况以及traceId、spanId都打印到它的访问日志之中,同时,会从ThreadLocal清理掉调用上下文。spanId生成算法如下:图2展示了一个浏览器请求可能触发的系统间调用以及生成spandId的关系图。对于现有的同类产品,往往依赖mq(消息队列,如Kafka)、bigtable(大数据,如HBase,Cassandra)等重量级解决方案,依赖较多。本发明的技术选型更加合理。数据采集端使用无状态的Http协议,通过批量上传的方式POST数据到数据收集端,保证传输效率,将对应用的性能影响控制在极低范围。也就是采用批量+HTTPPOST的方式发送数据,发送策略是批量发送,发送方式是POST方法,后面有对POST方法的解释。数据收集端通过高性能的nginx接收客户端上传的数据,部署简单,扩展方便。后端存储采用ElasticSearch,在保证吞吐量的基础之上,扩展了ad-hoc(点对点)的查询能力。自行开发了弹性计算框架,对物理资源的浪费极低。以上各环节都可以随着部署机器的增加,吞吐量和计算量达到水平扩展。本发明采用的方案需要减少对应用程序的影响,cicada客户端主要涉及到两个功能:一个是日志收集功能,一个是将收集好的日志发送到远程服务器的功能。前者通常耗时较少,且没太大优化空间;后者涉及到IO,处理较慢,性能优化主要针对后者。最终方案采用批处理+异步发送。那么,本发明采用下列措施增加日志吞吐量:一、批处理;二、用高性能、低延迟的消息处理框架Disruptor替换BlockingQueue(一种阻塞队列)作为线程间传递消息的框架,提升消息处理效率;对于日志传送过程中由于第三方原因(日志收集服务器挂掉、网络异常等)导致消息处理速度过慢,消息堆积可能导致内存溢出,本发明增加了连接超时设置和传输超时设置,超过一定时长的日志直接扔掉。对于各种原因(如程序异常)导致的单位时间内抓取的日志量过多的情况,本发明采用了限流处理,对于超过流量限制的消息,直接做扔弃处理。默认TPS(吞吐量)限制为2048条/s,此限制可以设置。通过以上方案,本发明能够透明的传递调用上下文,理解系统行为,理清后端调用关系,实现调用链跟踪,调用路径分析,帮助业务人员定位性能瓶颈,排查故障原因等;同时,需要对用户尽量透明,减少对业务代码的侵入性。本发明的整体架构说明:Cicada主要由日志采样模块、日志收集模块、日志存储模块、统计报表模块、UI模块这五大功模模块组成,模块彼此间的关系如图3所示。Client——日志采样模块当服务发生时,拦截分布式系统各组成部分的处理行为,记录行为日志并将日志通过HttpPost异步发送到日志收集模块。采用异步发送的原因是为了减少对业务响应时间的影响。对于由于程序异常导致的日志发送过快的情况以及由于网络异常导致的日志发送过慢的情况均作了处理,对于过快生成的日志,扔掉即可,同时报警提醒。对于过慢的日志,捕获异常,同时报警提醒。功能点如下:1、扩展实现DubboFilter,利用SPI技术透明接入,做到对Dubbo服务的无侵入式跟踪;2、利用Serverlet3.0注解申明的新特性,扩展实现对Http请求的拦截,做到透明接入;3、数据采样1)基于中间件创建调用上下文,生成埋点;2)调用上下文放在ThreadLocal,应用透明;3)上下文数据跟随分布式调用传递;4、埋点数据1)TraceID,使用uuid,保证全局唯一;2)事件所在的应用、接口和方法名;3)事件类型;4)事件开始时间;5)事件耗时。5、对于其他分散的服务,或者业务逻辑中其他小粒度的埋点,如服务内部的方法调用、数据库操作、URL请求等,提供注解以及api的方式。6、消息发送至数据收集服务;7、日志发送方案1)采用HttpPOST方式,批量异步上传数据;2)异步框架采用disruptor(一款异步调用框架),减少对业务的影响。日志收集模块日志收集模块分两个子模块:日志接收子系统和日志汇总子系统。1、日志接收子系统为简化开发和运维,日志接收子系统为nginx(一个高性能的HTTP和反向代理服务器)集群。nginx接收到客户端POST过来的消息数据,直接记录本地文件。2、日志汇总子系统1)从nginx日志中读取最新数据,记录读取进度;2)数据清洗;3)异步数据存储到ElasticSearch;采用这种方式的优点是开发和运维工作量小,方便水平扩展,可实现消息堆积。日志存储模块,本模块的作用如下所述:1)Span和Annotation数据存储在ElasticSearch;2)通过traceId可以直接将span数据关联起来;3)通过traceId和spanId可以定位所有的Annotation数据;4)统计结果存储在mysql。WEB——统计和报表模块定期日志统计,统计项包括以下:avgDuration:平均响应时间;minDuration:最快响应时间;maxDuration:最慢响应时间;line95Duration:95%line最大响应时间;line999Duration:99.9%line最大响应时间;failureRate:请求失败率;提供统计结果以及Trace数据访问的RESTful接口。UI——前端模块,指用户交互界面,展示分析结果。采用前后端分离的架构,通过ajax(一种创建交互式网页应用的网页开发技术)向统计端发送数据请求。为了提高页面渲染速度,使用React框架(前端开源框架)实现。本发明中相关名词解释:ZooKeeper:分布式服务框架,是Apache(全球知名开源基金会所)Hadoop(由Apache基金会所开发的分布式系统基础架构)的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、同步锁、Leader选举、队列管理、分布式应用配置项的管理等。Cicada-collector:数据清理模块,负责读取日志、清洗日志、汇总日志。Cicada-nginx:基于Tengine(知名开源WEB服务器)实现的日志存放模块。RPC:RemoteProcedureCallProtocol,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。ElasticSearch:基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。POST:HTTP协议中的一个重要组成部分。POST方法一般用来向目的服务器发出更新请求,并附有请求实体。Nginx:一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。当前第1页1 2 3 当前第1页1 2 3 
再多了解一些
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1