技术平台 & 应用开发专题月 | 一文搞懂全链路监控系统(下)
一、如何实现全链路监控?
基于 Dapper 规范,即可确定全链路监控的基本框架。然而,如前文所述,为实现全链路监控仍有诸多难题需要解决。
为了满足大规模混合云场景,尽最大程度保证链路完整性,全链路中的各个节点,无论微服务应用或是各中间件,无论部署于公有云或私有云,无论 Java 语言还是 Python、Go 语言应用,相互间的数据传递均要遵循同一套链路规范。
由此可知,全链路监控必须具备多语言协议栈统一、多端联动、跨云数据融合等特性。
01 多语言协议栈统一
在云原生时代,微服务架构下,多语言开发应用形式越来越普遍。不同语言自身具备不同的特性,利用这些特性可以更好的实现最佳性能并提升研发体验。但是,由于不同语言的成熟度差异,全链路监控并不能实现用户期待的功能完全一致性。
目前,业内通常的做法是统一远程调用协议层格式,在多语言应用内部实现调用拦截和上下文透传,以此来保证基础链路数据的完整性。
同时,为使全链路监控系统具有完备性,其应该提供更加全面、有效的数据监控能力。比如当业务出现故障时,可以提供代码级诊断能力;当资源占用过大时,提供内存及 CPU 分析能力;应用运行时,提供线程池分析能力等等。充分利用各个语言提供的诊断接口,最大化提升全链路监控的诊断能力,是完善全链路监控系统中不断追求的目标。
02 多端联动
目前,后端业务应用层的链路追踪相对完备,但在用户终端层和云端中间件相对缺少埋点及监控手段。其主要原因为终端及云端产品受用户定制或第三方定制影响过大,而通常业务方较难接入并影响终端及云端产品。
由此产生的问题是,当终端用户发现相应变慢时,难以直接定位到具体后端应用,给出定性的影响因素。类似的,当云端组件异常时,通常需要利用复杂而迂回的手段来定位问题。这对问题排查的时效性产生了极大影响。
03 跨云数据融合
出于易用性、扩展性、安全性等方便的考虑,目前很多大型企业选择混合云模式部署应用。即业务系统部署于公有云,Redis 缓存、CDN 等依托于第三方云服务,数据库等企业敏感信息部署于私有云,即自建机房中。可以说混合云部署已经成为了一种典型的云上部署架构。
由于云间环境仅可通过公网通信,为实现全链路监控的链路完整性,需要实现跨云数据上传,跨云数据查询等功能。
04 埋点及数据采集
埋点,顾名思义,在节点中埋入检测点,以采集业务运行时所产生的上下文信息。埋点可位于客户端埋点,服务端埋点等。埋点产生的日志通常需要包含 Trace ID,Span ID、调用开始时间、请求耗时、调用结果、异常信息等。
一般来说,全链路监控可以有三种手段采集数据:
1、手工埋点方式
这种方式需要开发者在自身的业务代码中手动埋点,生成符合标准及规范的链路信息后,汇集到全链路监控系统中。这种方式需要开发者主动配合,在业务代码中嵌入大量非业务相关逻辑,因此在推行时通常具有较大阻力。同时,受开发者的业务理解能力影响,稍有疏忽则可能使数据异常甚至丢失,影响监控数据的准确性。因而在非必要情况下,通常不采用手动埋点方式采集数据。
2、SDK 方式
这种方式对研发人员相对友好,通过引入全链路监控系统提供的 SDK 组件,在服务运行时自动生成数据并上传。但是,在底层架构没有公开相关 API 的情况下,监控数据的实现将变得较为复杂,开发者可能需要对底层架构事先做好准备工作。
3、探针方式
此种方式通常无需业务开发人员介入,而是在应用运行态,通过 agent 等方式动态拦截底层框架,自动注入监控逻辑。比如,Java 语言可以通过字节码增强技术实现监控探针的信息采集。此种方式对研发人员极度友好,省去了研发阶段的所有工作。然而,并非所有语言均提供类似的探针实现机制,现实中需要通过其他两种方式作为补充来满足不同类型应用的监控需求。
05 数据的统一收集与存储
埋点所生成的数据信息在上传或拉取后,需要进行统一的存储。之后可对这些数据进行聚合、清洗等操作,按照环境、应用等维度展示,进而以根据访问量,相应时间、错误率等关键指标分析,定位问题。
一般地,为保障全链路监控系统自身的高可用性,通常采用分布式日志采集方案收集与存储数据。同时增加 MQ 等缓存策略,分担存储压力。
06 数据展示与分析
当数据存储完成后,用户可根据自身需求查询数据。
例如,在指定一个 Trace ID 后,将查询出的全部 Span 按请求发起时间排序并展示,即可获得 Timeline 图表;按 Parent ID,以树状结构展示,即可获得调用栈示意图。
再比如,当应用运行出现异常时,可以根据调用栈查询业务日志,从而快速定位问题。
一些典型的利用全链路系统可以分析解决问题的场景有:
Web 应用过程分析:通过 URL 调用过程,分析消耗性能的主要原因
数据库性能分析:检测多种类型数据库数据,追踪定位慢 SQL 语句
NoSQL 分析:实时监控诸如 Redis、MongoDB 等 NoSQL 数据库的性能
应用错误分析:记录错误发生时间、调用堆栈,统计应用错误率
API 调用分析:检测外部应用发起 API 请求耗时、数量、时间、频率等
资源占用分析:分析各应用在各时间段的 CPU、内存等资源的占用情况
JVM 性能分析:实时检测 JVM 运行时状态,通过折线图、柱状图等形式展示内存分配及使用情况
二、如何评价一款全链路监控系统?
综合来说,评价一款全链路监控产品的标准,可从以下四个方面入手:
01、时效性
提供实时有效的监控数据显示功能,可以帮助相关人员了解系统行为,为流程、架构、代码优化、扩容减容、业务流限制降级提供准确、客观的数据参考。
02、评估探针性能消耗
一套全链路监控系统应该努力降低 APM 组件服务对业务性能的影响。由于监控埋点自身一定需要消耗一部分计算资源,因此有必要对其实际影响进行评估。一般认为对 CPU 的耗用低于 2%可以作为一个理想参考阈值。实践中,通常会设置采样模式,仅选择具有代表性的请求来进行分析。
03、可扩展性
一个优秀的全链路监控系统,理论上说,能够支持的组件越多越好。在一些无法覆盖监控的情形,或能够提供对应 API,或允许用户自行扩展,以增加监控的覆盖面,增强监控系统的完备性。
04、代码的侵入性
即使作为业务的一部分,全链路监控系统也应该尽量减少对已有业务代码的侵入性,以减少研发人员的负担,降低系统接入门槛和难度。因此,一般认为无侵入探针方式埋点要优于 SDK 方式。同时,SDK 也好于手动埋点。
三、总结
目前,市场上已有的全链路监控系统有 Pinpoint、OpenTelemetry、SkyWalking、Jaeger、Zipkin、CAT、普罗米修斯、ARMS、Hubble 等。各产品在成熟度、实现方式、完备性、易用性等层面均有所不同。比如,老牌的 Pinpoint 对 Java 类型应用集成度很高,但缺少对其他类型应用的支持,且缺乏中文文档支持;CAT 能够提供丰富的报表,但却以侵入式的方式实现监控功能;Zipkin 提供调用链路可视化功能,但能够提供的报表数量有限,且也以侵入式方式实现。
值得一提的是,用友公司出品的 Hubble 全链路监控系统,以无侵入式方式实现采集数据,且提供完整的链路展示,提供丰富的图表展示功能,且与其自有的技术平台紧密结合,实现从访问发起端经由 Nginx、Ingress、微服务应用、中间件等环节的完整链路监控与展示,并提供完备的预警及报警机制。其针对 Java 类型应用监控使用字节码增强方式实现探针埋点,简化用户操作到仅需开启监控开关即可实现对该类型应用的监控。
可以说,使用技术平台部署微服务架构应用,依托于 Hubble 全链路监控系统,当应用运行出现问题需要定位或希望进行性能调优时,能够快速有效的为用户提供帮助,最终让应用的稳定运行如虎添翼。
当然,我们深知,全链路监控目前在业内仍然处于发展阶段,打造一套对大型企业真正可用、好用、易用的全链路监控方案是我们追求的目标和使命。向上能够赋能业务,辅助业务决策,向下能够与基础设施联动,提前探测并感知风险,是我们对全链路监控系统的更高要求。
期待全链路监控系统在未来能够向更加完美的方向发展!
扩展阅读:
评论