随着虚拟化、云化技术越来越成熟,分布式系统的成本和架构优势日渐凸显,特别是微服务等设计理念在业务系统尤其是大型的互联网公司中越来越流行,业务的调用关系越来越复杂。
而随着业务的膨胀、服务的拆分,系统的模块变得越来越多,不同的模块可能由不同的团队/程序员来维护。一次客户的业务请求,可能会涉及数个乃至数十个服务的协同处理,牵扯到多个团队/程序员的维护模块,不同的缓存、数据库、消息队列等中间件。在这样的云化应用架构下,请求链路的任何一条请求出现故障或性能问题,都将严重影响服务的用户体验。如何能够快速准确的定位到线上故障根因?如何捕捉请求中的性能瓶颈并实施优化?如何将离散的业务请求数据关联在一起进行有效的用户体验分析?对于大型的、访问量大的网站、社交、电商、游戏应用,这类问题尤其突出,直接影响最终用户对系统的感知和留存率。
传统的应用运维问题定位以日志为主,通过对告警、系统资源、日志的逐一分析,定位故障根因或性能瓶颈。但是由于云化架构的复杂性,业务请求链路的多样性,传统的应用运维模式已经无法继续支撑故障定位与性能分析的诉求。这个时候就需要 APM 系统来大展身手了。
APM 的定义与演进
APM (Application Performance Management) 即应用性能管理,属于 IT 运维管理(ITOM)范畴。主要是针对企业关键业务的 IT 应用性能和用户体验的监测、优化,提高企业 IT 应用的可靠性和质量,保证用户得到良好的服务,降低 IT 总拥有成本(TCO)。APM 随着互联网的发展,经历了以下三个阶段:
第一阶段的 APM 出现在互联网兴起的初期,由于网络基础设施的水平普遍较差,使应用速度对网络速度与基础资源的性能非常敏感。这个阶段的 APM 以网络为中心,认为网络速度既应用速度,APM 主要监控主机的 CPU、I/O、内存、网络吞吐等为主。
第二阶段的 APM 以监控各种基础组件为主,随着互联网的发展,网络应用变得越来越复杂,各种基础组件越来越多,促使 APM 进入以 IT 组件的健康状态、可用性、性能监控为中心第二个阶段。
近几年移动互联网、云计算、大数据、物联网等技术的迅猛发展,各种业务应用不断出现,IT 应用复杂度呈现爆炸式增长,而互联网产品本身“用户至上”的属性决定用户体验成为各互联网产品生存发展的关键因素。如何提升用户体验,保证服务和产品的可靠性、稳定性、优化服务等问题,对应用性能管理提出了新的需求,应用性能管理进入以用户体验为核心、专注业务交易与应用架构高度复杂性的第三阶段。
基于 APM 市场分析,Gardern 对 APM 进行了新的定义描述:
在新的标准下,APM 市场发展迅速。APM 通过对应用服务的性能和可用性进行监控管理,帮助应用/服务开发者发现和定位性能瓶颈和故障,保证应用达到预期的服务水平及最终用户体验。
分布式追踪技术原理
现代的 APM 基本都是参考 Google 的 Dapper 体系来实现的。Dapper 通过跟踪请求的处理过程,来对应用系统在前后端处理、服务端调用的性能消耗进行跟踪。Google 基于 Dapper 的实现发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,给行业内分布式跟踪的实现提供了非常有价值的参考,该论文也成为了当前分布式跟踪系统的理论基础。大家可以参考 Dapper 论文原版,进行详细了解,本文只对原理做简单介绍。
如上图所示,对于业务链条中的每一次请求调用,划分为 clientSend(客户端发送请求)、clientRecv(客户端收到响应)、serverRecv(服务端收到请求)、serverSend(服务端发送响应)等四个事件,并由这四个事件组织为一个称作 Span 的数据结构。通过定义 Span 之间的调用(父子)关系,可以对离散的 Span 数据进行重组,以还原完整的调用链条。Span 间的关系通过 traceId、parentId、spanId 来标识。traceId 是一次完整调用链路的唯一标识,parentId 标识当前 Span 的前一个调用 Span,spanId 用来唯一的标识某一次调用。Span 在跟踪链路中的关联关系可以用下图表示:
基于 Google Dapper 这种通过 traceid、parentid、spanid 还原原始链路的思路,众多大型互联网公司都开发了自己的调用跟踪系统,如 Twitter 的 Zipkin、淘宝的鹰眼、京东的 Hydra、开源的 PinPoint,总体思路虽然一致,但是植入点选择上却有一些分歧。
分布式追踪采集技术两大流派横评
应用性能管理系统主要由数据源、采集传输、分析计算、可视化查询几部分组成,其中最核心的部分就是数据源。通过从客户端和服务端进行数据采集,其中客户端的数据采集技术主要包括主动式拨测与被动式埋点探测,在此不再展开详细描述,本文主要对服务端的数据采集技术进行简单介绍。
服务端的数据采集主要分为两大类:
网络旁路监听,通过在应用或服务部署的生产网络的交换机或网络接口抓取应用访问流量进行应用性能分析。这种方式对于应用或者服务的侵入性小,性能影响小。然而此方式采集粒度较大,无法提供代码级的问题定位,且在安全传输协议下,无法针对请求或事物进行分析。
探针埋点,通过在生产服务器上的应用部署或者嵌入探针的方式进行应用性能数据采集。这种方式能够提供非常完整与细粒度的监控数据采集,提供代码级的问题定位。但此方式对于应用来说是侵入性的,如果埋点代码异常,会对应用本身的性能和稳定性产生一定影响。
在针对应用与服务的埋点数据采集中,主要使用了探针埋点的方式。探针埋点的方式主要分为两类,以 Zipkin 为代表的代码侵入式埋点与以 PinPoint 为代表的字节码增强式埋点。
Zipkin 与侵入式采集 不依赖框架生态成熟
Zipkin 是 Twitter 开源的分布式追踪系统,用户帮助微服务收集排查潜在问题的时序数据,提供调用跟踪数据的收集、存储、查询以及依赖分析的能力。Zipkin 是一个分布式跟踪系统,不具备用户体验分析、应用监控统计等特性。Zipkin 使用代码侵入埋点的方式,官方提供基于 Finagle 框架的埋点方案,其他语言和框架的支持主要依赖社区贡献。当前支持包括 Java、Scala、Node、Go、Python、Ruby、C#等主流语言和框架。代码侵入式埋点指通过提供应用开发的 SDK,或者提供集成埋点代码的框架的方式供应用开发者调用。部分具备框架研发能力的企业像 Google 一样将植入点选在开发框架或通信框架中,确保基于统一框架开发或通信的应用天然具备埋点能力,除框架开发团队外无需关注埋点实现、调用方式。这种埋点方式优势在于使用框架后无需额外关注埋点能力,变相降低了埋点的成本。Twitter 的 Zipkin、淘宝的鹰眼选择了这种埋点方式。
同时,业界也有非常多的埋点装备库,支持使用埋点组件的方式实现调用链数据埋点。这种埋点方式,通过提供标准的服务框架,如:Servlet、Spring MVC、Http Client 以及通用的中间件,如 MySQL、Kafka 等的装备类的方式,通过编写简单代码和配置,让基于这些标准框架构建的应用可以输出调用链报告数据。Brave 为这种埋点方式提供了大量的标准框架实现。也提供了非常简单且标准化的接口,支持在以上的封装实现无法满足业务要求时,进行定制与扩展。
代码侵入式埋点具有较好的扩展性,方便用户自定义采集的数据类型与层次。但是,不论提供框架埋点的方式还是提供装备库、SDK 的方式,都需要代码侵入,在应用开发以及框架等升级场景下,应用需要重新修改代码。同时,对于应用开发人员来说,精准的识别需要埋点的地方也具有一定难度,而且基于代码侵入的埋点跟踪级别较低,无法获取足够详细的运行态信息。
PinPoint 与字节码增强式采集 深入埋点实现非侵入
与 Zipkin 不同,PinPoint 是一款开源的应用程序性能管理(Application Performance Management)工具,使用字节码增强的方式进行数据源收集,目前只有官方提供的 Java Agent 探针。字节码增强式埋点方式,提倡代码的非侵入性,不同的编程语言,通过不同的技术在语言运行环境或基础库上植入。对于 Java 应用,利用字节码增强技术,在启动 JVM 时通过不同的埋点插件覆盖不同的通信协议、中间件、开发框架,对 Java 基础调用代码进行函数级埋点。这种埋点方式优势在于能够拿到堆栈级的调用信息与其他更多运行态信息,帮助使用者无需日志等辅助手段即可快速完成问题定位。
PinPoint 使用字节码增强技术进行 APM 数据采集,通过在应用启动时配置 java agent 探针的方式,主动干预应用代码行为,应用开发者无需进行代码修改,由 PinPoint 来决定在哪些 API 进行数据埋点。相比较 PinPoint 的字节码增强技术与其他 APM 系统的代码侵入式埋点来说,字节码增强技术从理论上来说能够在任何地方进行埋点,而类似 Brave 装备库等侵入式埋点的方式本身依赖中间件的实现方式,其提供的应用层面的 API 还需要框架底层驱动的支持,才能实现拦截。
PinPoint 在实现之初就考虑到了性能优化,如采用 Thrift 的二进制变长编码格式、使用 UDP 作为传输链路、在传递常量的时候使用数据参考字典、使用异步传输方式等。但任然存在一些性能问题与使用的约束,并且由于字节码增强技术对开发人员有较高的要求,其在扩展性和社区生态方面具有一定的劣势。
华为 APM 的技术实践 零侵入式的全周期呵护
华为 APM 结合 PinPoint 与 Zipkin 两种典型系统的优点,提供更便捷、更高效、性价比更高的解决方案。
1. 非侵入式数据采集:一键式采集部署,更高效与健壮的数据采集能力
华为 APM 探针借鉴 PinPoint 采集探针优势,在采集数据模型、输出组件性能、可靠性等方面进行优化,并统计业界各框架与中间件的使用广泛性基础上,增加插件支持能力。以保证在最小的资源占用下,为用户提供最为有用的性能分析数据。
探针自动部署:华为 APM 支持与华为云容器引擎、云应用编排等服务配合使用,可以在应用部署时通过简单勾选,实现采集探针的自动部署。
支持 Zipkin 模型:虽然 PinPoint 与 Zipkin 均基于 Google Dapper 的论文,理论基础大致相同。但是在调用链的数据模型上还是有很大的差异性。在开放性以及社区活跃度等方面,Zipkin 更具有优势。为支持 Zipkin 用户接入,华为 APM 探针支持按照 Zipkin 的数据模型进行调用链数据输出。
数据分类优化:对于 APM 调用性能统计分析(吞吐量、平均时延、TPN 等),业界通用的方式为使用调用链数据进行二次抽取汇聚。该方式下需要尽量多的调用链数据样本,以使统计数据尽可能准确,势必消耗更多的应用资源。为解决这个问题,华为 APM 探针对采集数据源进行了分类:调用链数据与 KPI 数据。KPI 数据针对每个业务请求按照周期进行汇聚,输出包含请求发起方、请求服务方、调用事务、调用状态(耗时、成功或失败等)等信息。由于 KPI 数据周期性输出,且相比较调用链数据小得多,因此能够在很小的资源负载下实现全量请求采集与统计。
数据精准采集:调用链数据更多的关注调用超时(阈值支持自定义)或调用异常的调用链条。华为 APM 在基础采样率的基础上,从客户的实际运维场景触发,提供精准采集动态配置能力。精准采集支持客户针对应用或交易事务设置超时阈值、周期采集异常调用样本个数、周期内正常调用样本,以减少资源消耗的同时保证异常或超时请求的数据样本满足性能分析要求。
数据传输优化:针对大数据量下数据输出对资源的消耗较高的问题,对输出组件进行优化,通过异步文件输出与异步 Pipe 输出、输出数据 Cache,减少数据类型等方式,优化应用资源占用。
采集逃生机制:在高并发峰值场景下,应用业务请求多,资源消耗大。此时,为保证业务正常运行,华为 APM 支持用户自定义配置逃生资源阈值。在应用资源消耗达到阈值后,华为 APM 探针主动停止所有运维数据采集,在资源消耗下降至阈值以下时自动恢复数据采集。逃生机制支持动态配置。
2. 数字化运营:提供业务运营体验管理与性能分析
实时跟踪每条业务交易,快速分析交易的运行状态并提供诊断能力
自定义事务:用户可根据每条 URL 定义事务名称,方便理解。
健康规则配置:可以对每条事务配置健康规则,如超过 1s 提示异常。
性能追踪:精确采集异常性能数据,可对比历史基线数据,也能找到应用的异常方法,提升运维效率。
3. 应用程序分析:应用关系与异常一目了然、故障下钻
应用发现与依赖关系:精确采集异常性能数据,可对比历史基线数据,也能找到应用的异常方法,提升运维效率。
应用 KPI 汇聚:微服务实例汇聚到应用,KPI 数据自动汇聚到应用。
4. 应用程序跟踪:对异常业务调用链追踪,快速问题定界
支持平台、资源、应用的监控和微服务调用链分析:
海量数据规模支撑:支持百万容器监控,秒级查询响应。
故障下钻:通过单击故障节点可自动下钻到故障的微服务实例、也可以关联到失败的调用链和调用栈,查看失败函数的入参和返回值。
APM 采集技术介绍完了,还有更多干货是否还想继续深入了解呢?
本文转载自 华为云产品与解决方案 公众号。
原文链接:https://mp.weixin.qq.com/s/oRWbhucyzN-Z4OCMqTB0OA
评论