概述随着微服务架构的流行,服务按照不同的维度进行拆分,往往一个请求涉及多个服务。互联网应用程序建立在不同的软件模块集上。这些软件模块可能由不同的团队开发,可能使用不同的编程语言实现,可能部署在数千台服务器上,跨越多个不同的数据中心。因此,需要一些能够帮助理解系统行为和分析性能问题的工具,以便在出现故障时能够快速定位和解决问题。全链路监控组件就是在这样的问题背景下诞生的。最著名的就是谷歌公开论文中提到的GoogleDapper。要了解分布式系统在这种情况下的行为,有必要跨不同的应用程序和不同的服务器监视相关的操作。分布式服务调用链路在一个复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路。一个完整调用链的请求可能如下图所示:一个完整调用链的请求那么在业务规模越来越大,服务越来越多,变更频繁的情况下,面对复杂调用环节:如何快速发现问题?如何判断故障范围?如何梳理服务依赖和依赖的合理性?如何分析链路性能问题和实时容量规划?同时需要关注请求处理过程中每次调用的性能指标,如:吞吐量(TPS)、响应时间和错误记录等。吞吐量,对应组件、平台的实时吞吐量,可以根据拓扑计算出物理设备。响应时间,包括整体调用的响应时间和每个服务的响应时间。错误记录,根据服务返回统计单位时间内的异常次数。全链路性能监控展示从全局维度到局部维度的各项指标,集中展示跨应用的所有调用链的性能信息。故障排除时间。借助全链路监控工具,可以实现:请求链路跟踪,故障快速定位:通过调用链结合业务日志,快速定位错误信息。可视化:每个阶段的耗时,进行性能分析。依赖优化:各调用环节的可用性,梳理服务依赖并优化。数据分析与链路优化:可获取用户行为路径,汇总分析可应用于众多业务场景。1、全链路监控的目标如上,那么我们选择全链路监控组件的目标要求是什么?GoogleDapper中也有提到,总结如下:1.探针的性能消耗2.APM组件服务的影响应该足够小。服务调用埋葬本身会带来性能损失,这对调用跟踪的损失要求不高。在实践中,会选择一部分请求,通过配置采样率来分析请求路径。在一些高度优化的服务中,即使是很小的损失也很容易被注意到,并可能迫使直播服务的部署团队不得不关闭跟踪系统。3、代码的侵入性4、即使作为业务组件,也应该尽可能少或不侵入其他业务系统,对用户透明,减轻开发人员的负担。5.对于应用程序员来说,不需要知道有跟踪系统。一个追踪系统要想有效,就必须依赖应用开发者的积极配合,所以这个追踪系统太脆弱了,往往因为追踪系统在应用中植入的代码有bug或者疏忽,就会出现问题在应用程序中,这是不可能的。满足跟踪系统“无处不在”的需求。6、可扩展性7、一个优秀的呼叫跟踪系统必须支持分布式部署,具有良好的可扩展性。当然可以支持的组件越多越好。或者提供方便的插件开发API。对于一些不受监控的组件,应用开发者也可以自行扩展。8、数据分析9、数据分析要快,分析维度要尽可能多。跟踪系统可以提供足够快的信息反馈,以对生产环境中的异常情况做出快速反应。综合分析,避免二次开发。2.全链路监控功能模块一个通用的全链路监控系统大致可以分为四个功能模块:1.埋点和日志生成埋点是系统在当前节点的上下文信息,可以分为客户端埋点、服务端埋点、客户端和服务端双向埋点。埋点日志通常包括以下内容traceId、spanId、调用开始时间、协议类型、调用者ip和端口、请求的服务名称、调用时间、调用结果、异常信息等,并预留可扩展字段用于扩展中的Prepareforexpansion下一步;2、日志的收集和存储主要支持分布式日志收集方案,同时加入MQ作为缓冲;每台机器上都有一个daemon,用于日志收集,业务进程将自己的Trace发送给daemon,daemon发送CollectTrace,向上层发送;多级收集器,类似pub/sub架构,可以负载均衡;对聚合数据进行实时分析和离线存储;离线分析需要聚合同一调用链的日志;3、分析统计调用链路数据,时间敏感的调用链跟踪分析:收集相同TraceID的span,按时间排序,形成时间线。将ParentID串在一起就是调用栈。抛出异常或超时,并在日志中打印TraceID。使用TraceID查询调用链,定位问题。依赖度量:强依赖:调用失败会直接中断主流程高依赖:在一个链接中调用某个依赖的概率高频繁依赖:在一个链接中调用同一个依赖的次数较多离线分析:通过TraceID,通过SpanID进行总结和ParentID还原调用关系,分析链接形式。实时分析:直接分析单条日志,不做汇总重组。获取当前QPS,延时。4.显示与决策支持3.GoogleDapper3.1Span基本工作单元,一次链接调用(可以是RPC、DB等,没有具体限制)创建一个span,并用64位的ID标识。uuid比较方便,span中还有其他数据,比如描述信息、时间戳、键值对(Annotation)标签信息、parent_id等,其中parent-id可以表示span调用链接的来源。跨度上图说明了跨度在大跟踪过程中的样子。Dapper记录span名称,以及每个spanID和parentID,以在跟踪期间重建不同span之间的关系。如果一个跨度没有父ID,则它被称为根跨度。所有跨度都附加到一个特定的跟踪并共享一个跟踪ID。3.2TRACE类似于一个树状结构的Span集合,代表一个完整的trace,从请求到服务器开始,到服务器返回response结束,跟踪每一次rpc调用的耗时,并且有唯一性标识符trace_id。例如:你运行的分布式大数据存储的一个Trace由一个request组成。Trace的每个颜色注释标记一个span,一个链接由TraceId唯一标识,Span标识发起的请求信息。树节点是整个架构的基本单元,每个节点都是对span的引用。节点之间的链接表示跨度与其父跨度之间的直接关系。虽然span在日志文件中只是简单的表示span的开始和结束时间,但是在整个树结构中它们是相对独立的。3.3Annotation注解用于记录请求特定的事件相关信息(如时间),一个span中会有多个annotation注解描述。通常包含四个注解信息:(1)cs:ClientStart,表示客户端发起请求(2)sr:ServerReceive,表示服务端收到请求(3)ss:ServerSend,表示服务端有处理完成,将结果发送给客户端(4)cr:ClientReceived,表示客户端已经获取到服务端返回的信息4.方案对比市面上大部分全链路监控理论模型都是基于GoogleDapper论文,主要有以下三个APM组件:Zipkin:由Twitter开源,一个开源的分布式跟踪系统,用于收集服务的时序数据,解决微服务架构中的延迟问题,包括:数据收集、存储、搜索和展示.Pinpoint:一个用Java编写的大型分布式系统的APM工具,韩国人开源的分布式跟踪组件。Skywalking:一款优秀的国产APM组件,是一个对JAVA分布式应用集群的业务运行进行跟踪、告警和分析的系统。相比之下,Pinpoint具有压倒性的优势:无需更改项目代码即可部署探针、跟踪数据细粒度到方??法调用级别、强大的用户界面以及几乎全面的Java框架支持。
