Golang Agent 可观测性的全面升级与新特性介绍
作者:张海彬(古琦)
背景
自 2024 年 6 月 26 日,ARMS 发布了针对 Golang 应用的可观测性监控功能以来,阿里云 ARMS 团队与程序语言与编译器团队一直致力于不断优化和提升该系统的各项功能,旨在为开发者提供更加全面和深入的应用性能监控体验。
在这段时间内,ARMS 推出了多项关键功能,包括:
- 全链路的追踪: 支持前端、网关、后端服务的全链路追踪,实现端到端的全链路打通。
- CPU Profiling: 通过提供详细的 CPU 使用情况分析,帮助开发者识别性能瓶颈,优化代码执行效率。
- 内存 Profiling: Golang Agent 引入内存使用分析工具,帮助监测内存分配和泄漏情况,提高应用的内存管理能力,确保服务的稳定性。
- 本地错慢全采: 新增的错慢全采功能使得系统能够捕捉到应用中的错误和延迟事件,从而帮助团队快速诊断问题,提升用户体验。
- 新增插件: 为扩展监控能力,Golang Agent 新增多个插件,支持不同场景和需求,用户可以灵活组合使用,满足个性化监控需求。
- 日志 Trace 关联: 通过将日志与执行路径关联,提升了问题追踪的效率,开发者能够快速定位故障根源,从而减少故障恢复时间。
- 动态开关: 为了更好地满足不同环境和使用场景的需求,Golang Agent 实现了动态开关功能,允许用户灵活控制监控开启和关闭,提高系统的灵活性和可管理性。
- 性能提升: 性能上相比 1.0.0 提升了 35%+ 以上,极大的降低了资源的消耗。
- Windows: 支持 Windows 环境编译、运行,与 Linux、Mac 上都有相同的体验。
通过这一系列的功能升级,ARMS 希望能够帮助开发者更好地理解和优化他们的 Golang 应用,从而提升整体服务质量和用户满意度。未来,ARMS 将继续关注用户反馈,持续改进和扩展监控功能,为 Golang 应用的可观测性提供更强有力的支持。接下来我将逐个介绍一下 Golang Agent 的新增功能。
全链路追踪
为了实现前端 + 网关 + 后端服务的全链路追踪,Golang Agent 支持了常见的 Trace 透传协议如 w3c、b3、jaeger、EagleEye,实现多个不同类型的语言的应用之间 Trace 透传,Golang 服务内部支持 Span Context 的透传,无需要手动传递 Context,即可实现服务内部链路打通,同时还支持跟 OpenTracing SDK、OTel SDK 兼容,针对自定义的 Span 同样可以做到传递。
持续剖析
pprof 是 Go 语言内置的性能分析工具,允许开发者分析程序的 CPU 和内存使用情况。通过引入 net/http/pprof 包,开发者可以在 HTTP 服务器中开启性能分析功能,从而实时获取程序的运行状态、堆栈信息和内存分配情况等。
但是手动的在代码里面添加 pprof 的端口,获取对应的应用运行情况需要请求这个应用,同时需要有图表展示,使用比较非常麻烦,同时长时间开启 pprof 可能会有一定的性能开销,因此 Agent 在功能上支持随开随关,可以通过开关动态控制这个采集过程,还支持了 pprof 数据的在线查看和对比。
CPU Profiling
通过开启持续剖析的能力,就可以在应用诊断上查看到对应时间段的 CPU Profiling 数据,同时可以支持 Profiling 数据的对比,通过 CPU Profiling 的视图可以非常方便找出服务的性能瓶颈。
内存 Profiling
除了 CPU Profiling 外,内存的 Profiling 同样重要,对于分析内存的异常分配、内存泄漏起到关键作用,通过开关打开内存热点后,在性能分析类型下可以看到应用的内存分配大小、内存分配的次数。
本地错慢全采
由于采样率的限制,并非每条调用链都能被采集和上报,这在遇到问题时常常导致无法追踪到应用的调用链路。为了解决这一问题,除了调整采样率外,在 Agent 中针对错误和处理缓慢的请求实施全采样策略。这一措施确保所有发生的错误和缓慢请求都能被及时捕捉到,从而为后续问题的分析提供有效依据。
同时,为了优化性能,对如 Redis 等关键服务的调用进行压缩处理,以避免过多的 Span 导致 Trace 链路变得过于冗长。这一措施不仅减少了上报的数据量,还提升了系统整体的追踪效率。通过这些改进希望能够更准确地定位和分析应用中的问题,为开发团队提供更可靠的支持。
可以看到优化前的 Span 展示如下所示(这里对 Redis 进行了循环 10 次的 get、set 请求):
开启错慢全采后:
Span 减少非常多,同时对于错误和慢的 Span 会全部上报,这样既保证了问题查询,又能进行数据压缩降低成本。
新增插件
从 1.1.0 版本的 20 款插件,目前 Golang Agent 的 1.3.0 版本支持了 38 款插件,新增了很多常用的 SDK 支持,如:
- 消息:Kafka
- RPC:hertz、thrift、iris、fiber、kratos
- SQL/NoSQL:elasticsearch、redisv8、redisgo(https://github.com/gomodule/redigo)
- 日志框架:logrus、zap、zerolog,以及 golang 的 log、slog
对于 OpenTracing Go SDK 也做了支持,通过 OpenTracing SDK 的创建 Span、Span End 等操作都可以无需修改即可在 Trace 链路进行绑定。
针对函数计算 FCGo 的 SDK(https://github.com/aliyun/fc-runtime-go-sdk),有在函数计算下部署 Golang 应用的场景,针对 FC Event 的接收和处理的监控,使用 Golang Agent 编译对应的 FC Go 程序,在 FC 运行接收流量后可以在 ARMS 控制台查看到应用对应的监控情况。
更多的插件相关的支持和对应的版本,可以查看。
日志 Trace 关联
通过错慢全采的能力完善了 Trace 采样导致的 Span 被丢弃的问题,为了更好的定位到问题的原因,将 TraceId、SpanId 打印到对应的调用日志中,在日志插件支持方面支持了 logrus、zap、go 自身 log、slog 以及 zerolog 等日志框架。
动态开关
针对 Agent 提供的非常多的功能和插件,为了能实现功能的按需开启,在应用配置上增加了非常多动态开关能力:
1)针对每个插件,Agent 提供了插件的动态开关,默认情况下打开,如不需要采集某些 SDK 的数据,可以动态关闭。
2)日志关联配置,可以将 TraceId、SpanId 关联到对应的日志上,并在 ARMS 控制台实现日志 Trace 关联,这里可以配置对应的日志采集的 Project、LogStore 等。
3)持续剖析,可以配置 CPU Profiling、内存 Profiling 的动态开关。
4)数据库配置,可以配置是否展示 sql 语句的请求参数、sql 语句的长度配置、sql 超时配置等。
5)接口调用配置,设置接口的超时时间、对哪些接口、状态码进行过滤。
Windows
之前的版本在 Linux、Mac 上进行编译运行,在新的 1.3.0 版本中增加了对 Windows 的编译和运行的支持。
RoadMap
-
代码热点,通过持续剖析技术定时采集请求线程堆栈快照,真实还原代码执行的第一现场。
-
自定义扩展,方便快速定制开发。
-
Golang 的内存泄漏、goroutine 泄漏等异常事件的检测
....
同时基于 OpenTelemetry 的协议的 Golang Agent 已经开源,目前已经发布到0.2.0 版本,支持了超过 15+ 的插件。
[1] 《全链路追踪 & 性能监控,GO 应用可观测全面升级》
[2] 应用对应的监控情况
[3] 更多的插件相关的支持和对应的版本
[4] Golang Agent 已经开源
https://github.com/alibaba/opentelemetry-go-auto-instrumentation
点击此处立即开通 ARMS - 应用监控,享受每月 50GB 免费额度!加入钉钉群(群号:35568145)获得在线技术支持。