高途自建APM之路
什么是APM
APM(Application Performance Management, 应用性能管理)是一种软件工程领域的方法论,旨在监控和优化应用程序的性能,确保其在不同环境中稳定高效地运行。APM系统通常包括性能监测、故障诊断、事务跟踪、日志分析等功能,以提供全面的性能管理。

性能监测是APM的核心组成部分,通过实时监控应用程序的各个组件,从而获得关键性能指标。故障诊断则用于快速定位和解决应用程序中的问题,提高系统的可靠性。事务跟踪允许开发人员追踪特定事务在系统中的执行路径,以便深入了解性能瓶颈和优化机会。日志分析则通过分析应用程序生成的日志,帮助发现潜在的问题和趋势。
APM在当前云计算和分布式系统的背景下变得尤为重要。企业和开发团队借助APM可以实时监控应用程序的运行状况,快速响应问题,提高用户体验和业务连续性。通过全面的性能管理,APM也为开发者提供了数据洞察,帮助他们改进代码、优化系统架构,并不断提升应用程序的质量和效率。
有哪些APM
2020年下半年,高途业务开始上云,同时逐步建设基础设施。当前较流行的APM系统有阿里云的Arms、美团点评的CAT、开源的PinPoint和SkyWalking等等。
调研几种方案,对比如下表:
为什么要自建APM
Agent方面:
项目多feature并行开发和测试需求很大,测试环境争抢和冲突严重;搭建多套环境成本太高,希望构建复用+隔离的多版本测试环境;通过SkyWalking Agent构建流量调配能力,实现环境隔离,构建了魔方项目(多泳道、多版本测试环境);APM方面:
部门最开始选用的是原生SkySalking,服务端不稳定,发生了线上事故,且UI难用,rd伙伴体感很差;切换到阿里云arms,按 实例 x 时间 收费;且与SkyWalking Agent冲突;测试环境未部署arms,测试环境APM数据缺失,因为缺少数据支撑而无法开展压力测试;arms默认采样率是10%,丢数严重,rd伙伴反馈缺少问题现场数据,定位问题很困难;当时arms缺少P90、P99等指标,阿里方面需求响应很慢,大概半年后才提供,且不完全满足需求;最初开始做APM的时候(2020年下半年)基础架构的一些规划:
灰度发布
线上环境灰度发布,小流量验证;白天发布,不再需要等待23点才开始;需要agent提供流量调配、标记能力;灰度验证效果,需要后台提供流量追踪和分析能力;全链路压测
需要agent提供流量染色标记、服务隔离、资源隔离等等能力;压测过程监控和结果分析,需要后台提供流量追踪和分析能力;监控告警
基于APM指标的监控告警,需要自己构建后端服务;现在(2023年下半年)这些规划都已经基于自建APM体现实现。
方案
难点
可靠
agent要稳定,即使出异常也不能影响业务逻辑;agent对宿主影响小(总体影响不超过5%),保证数据丰富性和完整的同时,做到对宿主影响可靠;后台系统可用性要高,要做最可靠的系统;快
用户操作生效快,配置变更后秒级生效;指标计算快,能够近实时看到应用性能表现;告警快,目标是1分钟发现问题并告警;总体方案
Agent基于SkyWalking深度二次开发,服务端完全自研。
Agent选择SkyWalking是因为其源码更容易看懂,插件结构更容易修改和新增。现在来看,SkyWalking在开源APM领域呈现出了遥遥领先的生命力。
服务端是结合了众家之长,Arms的灵活实时配置,CAT的高效预计算,PinPoint的高效问题分析。
Agent方案
配置更新
agent启动时会自动读取本地的默认配置文件,加载必要的配置信息。然后启动循环的长轮询,尝试从服务器更新最新的配置。以实现配置的实时下发实时生效。
数据上报
原生是通过RPC方式上报数据,高峰期服务器的压力很大。我们曾改成写文件然后通过filebeat收集的方式上报,经验证效率较低。最终我们选择的Kafka通道上报数据。
经验证我们16台4C16G的服务器,设置32个分区,极限可承载160万条/秒。为应对未来更高的流量,同时避免单点故障,我们采用了多Kafka集群的方案。使用一致性Hash算法,根据应用名映射到集群,同时支持服务端实现下发集群配置,能够快速扩容和故障转移。
数据采样
为了保证数据丰富性和完整的同时,减少数据量,减少对宿主的影响,我们设计了自适应采样算法。
服务端方案
数据计算
消费
弹性扩容,根据负载自动扩容;;堆积分发,当部分partition数据堆积时,把数据发到新的topic,加速处理;保护丢弃,数据堆积严重,超过阈值时开始丢弃旧数据,处理最新数据;计算
多线程并行计算;无锁设计,根据聚合字段分发数据,不需要加锁;内存计算,2小时内数据走内存,2小时外数据查库;数据查询
2小时内数据查询内容,2小时外数据查询数据。
存储方案
trace详细数据都存储在ClickHouse中,得益与其强大的批量存储,支持每秒百万QPS数据写入。
前期预聚合数据存储在PolarDB中,随着接入应用的增加,数据量急剧增加,PolarDB已经无法承载,隐藏我们将预集合数据也迁移到了ClickHouse。
JVM相关指标数据,存储在ES中,方便与grafana集成,实现告警功能。
OpenTelemetry集成
2022年下半年,Java语言的APM覆盖已完成,而其他语言的APM能力缺失。经调研 OpenTracing和OpenCensus项目合并为OpenTelemetry,成为新的可观测性方案,同时SkyWalking 8.x也提供了对OpenTelemetry的各语言的支持。
而我们二开的Agent是基于SkyWalking 7.x的,两者协议上有所差异。为了能更快更容易的完成整合,我们决定采用如下方案。Java的Agent支持8.x的协议,其他语言使用8.x的SDK。这样可以解决其他语言的APM接入问题,同时可以实现跨语言的trace串联。
协议兼容方案如下:
成果
Java应用100%覆盖,也支持了NodeJs、Python、Go、C/C++等其他语言,同时Nginx和apisix日志也纳入了APM体系;每日处理数量超过300亿,历史数据峰值约100万条/秒,数据延迟在1分钟以内;构建了问题分析、性能分析、链路上下游、依赖分析、应用大盘等等约20项能力,GAPM也构成了端到端可观测性的重要组成部分;同时GAPM的后端服务能力也在前端监控和Nginx监控中得到了复用,构建了统一的计算、存储、展示和应用的平台能力;另外,我们也基于GAPM Agent构建了灰度能力和全链路压测能力;下面是部分功能界面截图。问题分析
慢和异常的数据统计,适合和IP上的分析。
性能分析
小时、日、周、月维度的性能统计和分布。
依赖分析
应用和资源上下游自来关系。
trace查询
端到端的trace链路展示。
前端监控-会话查询
前端监控能力的支持。
Nginx监控
Nginx监控能力的支持。
应用大盘
全局视角的应用状态。续班、大量上课等重要业务活动保障时,应用大盘是重要的业务健康看板,基础架构会专人盯应用大盘。
实时拓扑图
分钟级的流量和依赖关系。
实时排行榜
分钟级的慢、异常排行榜。
告警
支持慢、异常的分钟级告警。告警中会携带最新一个trace id,方便通过分析trace链路,快速分析定位问题。然后通过分钟级的快速回滚、重启或扩容等操作解决问题。
未来
经过近3年的时间,通过在业务实践中不断打磨,不断优化升级,高途自建APM功能完整度和成熟度都已经较高。未来还有2个可以进一步改善的地方:
Agent切的更早,切的更细。当前SkyWalking数据采集的切入点是在业务层,如果请求参数或方法错误,框架层就会异常返回,一般表现为4xx错误,这时候还没有进入Agent的切点,无法捕获线程信息。要解决这个问题就需要Agent切的更早,在框架开始处理请求的时候切入。
SkyWalking是基于组件的数据采集,粒度较粗,不像PinPoint是基于方法的数据采集。在分析性能问题的时候,可能会遇到追踪到某个组件或方法耗时较长,更深更细的耗时就没有了,需要其他技术手段辅助分析,如Arthas。要解决这个问题就需要Agent切的更细,分析业务常用组件,增加更多的切点。
非Java语言覆盖。高途90%以上的应用是Java应用。这也是我们首先对Java做支持,而且支持做的最好的重要原因,目前Java应用已100%覆盖。同时公司还有一些应用使用的是其他语言,如NodeJs、Python、Go和C++等等。我们通过整合OpenTelemetry方案对这些语言也做了支持,目前覆盖还不高,后续要继续推广,提高非Java语言的覆盖。
作者:冯贵龙蔡沈锦艾明
来源:微信公众号:高途技术
出处:https://mp.weixin.qq.com/s/nOyGjSl_zc4lERb8GZrIiQ