文/系统运维 SIG
01
背景
云上环境,ECS 用户一般都会布置一些常规监控观察系统指标或者业务指标,虽然通过这些指标能监控到系统或者应用的异常,但却不能完全了解系统/应用正在做什么导致的指标异常。常见的如:看到系统 CPU 偶尔飙高却不知道是哪个应用引起、抓包发现报文已经到达了本机却不知道应用为何迟迟不收包等等,束手无策之余只能认为“系统有问题” ,而在排查系统问题之后发现往往是应用对系统资源在做一些野蛮消耗,这些应用有些是业务自身,有些则悄悄躲在 "ps -ef" 的千百个任务中,很难发现。于是我们想通过 profiling 的方式去观测系统/应用的运行行为,帮助用户解决难题。
02
实现方案
所谓的"profiling"可以认为是以一种动态的方式去观测程序的执行逻辑。这个程序可以大到一个操作系统,甚至是一个基础设施,有兴趣的同学可以看下文[1],也可以小到一个 pod,甚至一个简单的应用程序。如果在这种方式上再增加一个时间维度,持续性的以“profiling”的方式去做观测,对上面说的常见系统资源偶现指标异常等问题就可以做一个很好的追踪,不需要苦苦守着问题出现。
那么如何去做 profiling 呢?
不同的编程语言有不同的 profiling 工具,像 Go 的 pprof、Java 的 jstack 等,这里我们希望观测应用但又想抛开语言的差异化,于是我们借助 eBPF 来实现程序栈信息的获取,这里的栈信息包括一个应用在用户态执行和内核态的执行的全部信息。借助 eBPF 的好处在于我们可以做到 profiling 过程的可控 :频率快慢、运行时安全、系统资源占用小等。
如下图所示,通过 eBPF 加 PMU(Performance Monitoring Unit)事件我们就可以定期获取应用的执行栈信息,同时利用 bpf map 对每个应用的栈信息做统计。借助我们前期开源的 Coolbpf(eBPF 开发编译框架,具备 CORE、高低版本适配能力),我们对不同的内核版本做了相关适配,具体可执行版本见下文。
profiling 应用的那些行为逻辑
一个程序的运行时最简单的可以概括为执行和不执行两种状态 ,即 on cpu 和 off cpu。on cpu 我们希望看到程序占用 CPU 时的执行逻辑,哪个任务甚至任务的哪一段代码在 CPU 上消耗资源,而 off cpu 我们希望看到应用是否是自愿放弃的 CPU,出于何种原因不占用 CPU,如等锁、等 IO 等,以此希望发现一些应用等损耗时造成的收发包延迟等问题。
针对网络抖动的常见问题我们在收包的两个阶段:
1. 硬中断和软中断收包。
2.用户态应用进程系统调用取包,也做了相关的 profiling 观测:
如何持续的 profiling
整体我们采用 c/s 的架构方式,日常问题定位中我们只需要部署 agent 去负责 profiling,在 server 端去查看数据。同时将 profiling 数据做切片处理,定时从 map 中拿数据并清空 map 上一周期的采样数据,这样的话确保我们在做数据回放的时候看到的是对应时间段的 profiling 结果 。考虑用户对云上环境数据安全的要求,我们也可以借助 SLS 通道完成数据上传。
03
使用说明
在 SysOM 上可以有两种使用方式。
如果想持续性的观测系统那么可以监控模式下 profiling 功能,对应路径在:监控中心->机器 ip->General dashboard->sysom-profiling。
如果是想获取 profiling 的一些结论性信息可以通过诊断模式,对应路径在:诊断中心->调度诊断中心->应用 profile 分析。
当前会统计 top 10 应用 CPU 占用百分比,同时会将热点栈信息展示出,热点栈在应用自身所有栈信息的百分比也会做一个统计,最后会对热点栈做个分析,明确热点栈是在应用自身还是在 OS。
以上展示的是 oncpu 的面板信息,profiling 的其他功能的面板信息持续适配中。
具体 profiling 功能可以执行 sysAK 统一监控目录下的 raptor 获取,除了功能项也可以设置运行模式等。