当前位置: 首页 > 科技观察

京东分布式服务跟踪系统-CallGraph

时间:2023-03-14 22:14:00 科技观察

一、CallGraph的背景随着京东业务的快速增长,京东的研发系统相继实施了SOA和微服务策略,以应对日益复杂的业务和急剧增加的应用类型。这些分布式应用相互依赖,共同完成京东所有业务场景。它们动态变化的复杂程度和数量都超出了想象。监视它们并试图控制全局超出了人类的能力。迫切需要一种软件工具帮助相关人员了解系统行为,从而为流程优化、架构优化、程序优化、扩容、限流、降级等运维行为提供科学、客观的依据。根据谷歌为其基于日志的分布式追踪系统Dapper发表的论文,CallGraph由京东基础平台部自主研发,现已上线。业界也有类似的系统,比如淘宝鹰眼、新浪守望先锋等,但CallGraph不仅提供了与这些系统类似的功能,而且还有自己的特点,下面会详细说明。2、CallGraph的核心概念“调用链”是CallGraph最重要的概念。一条调用链包括从源头(如前端网页请求、无线客户端请求等)到底层系统(如数据库、分布式缓存等)等的请求,如下图所示.每次调用都会在源请求中生成一个全局唯一的ID(称为“TraceId”),并通过网络将TraceId依次传递给下一个链路。这个过程称为“数据透明传输”(简称“透传”),图中的每一个环节都会产生包括TraceId在内的日志信息,通过TraceId将调用链中分散在不同系统上的“孤立”日志连接起来,然后通过日志分析,重组和还原更多有价值的信息。3、CallGraph的特点和使用场景CallGraph本质上是一个监控系统,但是它提供了一般监控系统所没有的特性。每个特性都有其典型的使用场景,为相关人员提供了强大的排查方法和决策依据,总结如下:四、CallGraph的设计目标针对CallGraph等监控系统,特制定如下设计目标:1.低侵入性作为非业务系统,应该尽量少侵入或不侵入其他业务系统,并保持对用户的透明性,这样可以大大减轻开发者的负担和接入壁垒。2.性能影响小CallGraph通过对各个中间件jar包的转换来完成日志数据的生成和收集。我们称这种转变为“埋点”。由于埋点都发生在核心业务流程中,所以我们应该尽量减少对业务系统的性能影响。3.灵活的应用策略为了消除业务方因为使用CallGraph而对自身造成影响的顾虑,应该提供灵活的配置策略让业务方决定是否开启跟踪,以及数据收集的范围和粒度,并提供技术手段安全配置必须生效。4.时效性:从数据的生成和采集,到数据的计算/处理,再到展示,要求尽可能快。五、CallGraph的实现架构1.CallGraph核心包Callgraph-核心包被各个中间件jar包引用,具体的嵌入逻辑都在核心包中完成,各个中间件在合适的时候调用核心包提供的API完成嵌入点的地方;核心包产生的日志存储在内存盘上,由日志采集Agent发送给JMQ。(1)JMQJMQ是京东的分布式消息队列。利用其强大的性能,它充当日志数据管道,Storm会不断地消费其中的日志数据。(2)Storm利用Storm进行流式计算,组织日志数据并并行进行各种计算,并将结果分别存储在实时数据存储和离线数据存储中。(3)存储包括实时数据和离线数据存储。实时数据部分包括Jimdb、Hbase和ES。Jimdb是京东自有的分布式缓存系统,存储调用量、TP等实时指标数据;使用Hbase的SchemaLess特性来存储固化链接数据,因为不同的链接所包含的中间链接数量是不一样的,无法使用Mysql等具有强schema特性的存储。通过TraceId可以从Hbase中查询到某个调用的所有中间环节的信息。离线数据部分包括HDFS和Spark,用于海量历史数据分析,部分结果也会存储在Mysql中。(4)CallGraph-UI这是CallGraph提供给用户的交互界面。用户可以在其中查看自己所有系统的详细信息,以及各个系统中应用程序的调用链接,包括应用程序之间的依赖关系图。还可以对应用进行来源分析、入口分析、某个服务方法的路径分析、具体调用链路的详情等,还可以对应用进行“采样率”等配置设置。(5)UCCUCC是京东自己的分布式配置系统,CallGraph使用它来存储所有的配置信息,并同步到应用服务器的本地配置文件中。核心包会定期检查这些配置文件以使配置生效。当UCC出现故障时,也可以直接操作本地配置文件使配置生效。(6)管理元数据存储CallGraph的管理元数据,如链接签名与应用的映射关系、链接签名与服务方法的映射关系等;2.CallGraph的技术实现据说这部分属于架构图中CallGraph-core包的重点部分,也是比较难的部分。CallGraph-core包完成跟踪逻辑,如下图:前端应用和各个中间件jar包导入CallGraph核心包,前端应用使用web容器的filter机制调用核心包的startTrace开始跟踪,收到响应后调用endTrace结束在这个跟踪中,各个中间件在适当的地方调用核心包提供的clientSend、serverRecv、serverSend、clientRecv等原始API,其中,橙色完成“创建上下文”,绿色完成“生成日志”。为了进程间上下文的透传,调用上下文放在本地的ThreadLocal中,对业务是透明的。调用上下文在中间件的网络请求中传递,对端收到后重组还原为调用上下文。流程如下图所示:对于异步调用,会涉及到线程间的上下文透传。增强逻辑将通过java字节码增强的方式编织到CallGraph核心包加载期,以透明的方式完成线程间上下文的透明传输。这里又可以分为两种,一种是直接新建线程的方法,如下图,这种方法是通过增强JDK的线程对象(Thread)来完成的,子线程会使用到的上下文父线程作为自己的Context(图中的“子上下文”);对于使用Java线程池提交异步任务,不存在“父子”线程关系。此时通过JDK各种线程池的增强,实现了上下文透传,如下图:以上过程对开发者完全透明,对运维人员也非常方便,实现了“低侵入”。6、日志格式设计CallGraph的日志格式需要满足不同中间件的具体要求,同时保证版本兼容性。一般来说,CallGraph的日志格式分为固定部分和可变部分。固定部分由以下组成:TraceId、RpcId、开始时间、调用类型、对端IP调用耗时调用结果和中间件相关数据:如rpc调用的接口、方法、mq主题名等通信负载变量请求字节/响应字节的一部分是最重要的“自定义数据”。用户可以使用CallGraph-core包API添加自己的特殊字段。用于特殊目的。通过抽象设计,不同场景的日志格式都有专门的编码器类,在输出日志时一起使用。1.高性能链路日志输出为了完全避免与业务争夺I/O资源,CallGraph特地在应用服务器上开辟了一块专用的内存区域,并将其虚拟化为磁盘设备。核心包产生的日志存储在这样的内存盘上,完全不占用磁盘I/O,速度极快。同时开发了专门的日志模块。日志输出批量异步写入内存盘。当日志量过大时,采用“丢弃日志”的方式,将对业务的影响降到最低,如下图:2.TP日志和链接日志分离,尽量减少对业务性能的影响。实际上,在大多数情况下,“采样率”机制将被启用。大大减少日志生成。但对于TP指标,必须记录每次调用的TP值,否则提供的TP50、TP99、TP999指标将不准确,无意义。本质上,链路信息和TP性能指标是两种具有不同属性的数据。所以这两种数据在核心包中是独立处理的,互不影响。采用分离的日志收集和输出策略。TP指标处理如下图所示:3.实时配置在双11或者6.18大促的时候,为了保证业务的正常进行,各业务系统基本上都会采取降级非业务系统的措施。CallGraph提供了丰富的配置和降级方式来满足业务方的需求。CallGraph提供了基于应用、应用组、应用服务器IP的多维配置方式。每个维度提供“是否开启链路跟踪”、“链路采样率”、“是否开启TP跟踪”、“TP粒度”等配置项,供业务方根据情况使用。业务方通过CallGraph-UI管理端自行设置业务的各项配置项。所有的配置信息都存储在UCC(京东的分布式配置系统)上,同时也会同步到应用服务器的本地配置文件中。CallGraph-core包有专门的Daemon线程定时访问这些本地配置文件使配置生效;当UCC出现故障,无法正常访问时,也可以直接操作这些本地配置文件,保证配置立即生效。4、Storm流计算所有日志,无论是linklog还是TPlog,都要经过storm计算生成结果数据,分别存储在实时数据存储和离线数据存储中,如下图:离线分析bolt由一系列bolt组成,对链路日志信息进行分析,负责生成符合离线数据模型的结果数据。后续会通过spark/flume等大数据技术计算得到大时间尺度下的固定链接。一些特征指标,如调用次数、平均耗时、错误率等。实时分析Bolt分析TP日志信息,负责生成实时指标数据,存储在Jimdb中,供CallGraph展示-用户界面。5、实时数据分析——秒级监控这是CallGraph区别于其他同类系统的一大功能。其他同类系统只提供链路日志分析,而链路日志的分析需要积累海量数据,再借助大数据相关技术进行分析,实时性较低。为满足业务方对实时分析的需求,CallGraph使用分布式缓存系统Jimdb存储实时数据,可提供1小时内的实时分析结果进行源分析、入口分析、链接分析等.(Jimdb中数据设置过期时间,自动过期),涉及调用量、调用量占比、TP性能指标等的显示,该功能内部称为“秒级监控”。“二级监控”需要分析TP日志。原理如下图所示:LogRealTimeBolt会从LogTPSpout获取TP原始日志,进行整理、分析和计算,将结果暂时缓存在“本地缓存”中。条件统计后,分批聚合到Jimdb存储中。这样做的好处是先在本地进行组合计算,同时也减少了Jimdb的I/O次数。7、CallGraph的未来京东CallGraph的历史还很短,未来还有很长的路要走。为进一步满足业务方对CallGraph的需求,CallGraph未来将逐步完善并提供以下功能:进一步优化实时数据的处理机制,让延迟更低,实现真正的“实时”;目前该功能需要采集日志、JMQ、storm等进程,所以有十几秒到几十秒的延迟,属于“准实时”的范畴;完善实时错误发现和告警机制,进一步提高发现问题的及时性;接入更多的中间件进一步丰富了调用链的内容,使得调用链更长更完整;提供完整的API接口,与兄弟团队共享调用链数据,构建属于自己的调用链分析系统;借助深度学习算法,进一步挖掘链上历史数据的价值,力求在更多维度上提供有价值的分析数据。【本文来自专栏作者张凯涛微信公众号(凯涛的博客)公众号id:kaitao-1234567】点此查看作者更多好文