云优采集接口(本文的原理机制,如何使用火焰图快速定位性能问题)

优采云 发布时间: 2021-11-09 02:08

  云优采集接口(本文的原理机制,如何使用火焰图快速定位性能问题)

  本文主要分享火焰图的使用,介绍了systemtap的原理和机制,如何使用火焰图快速定位性能问题的原因,同时加深对systemtap的理解。

  让我们回想一下,作为编程新手,我们是如何调整程序的?当没有数据时,它通常基于主观假设。稍有经验的同学会二分不同的代码或者一块一块调试。这种定位问题的方法不仅费时费力,而且不具有普遍性。当遇到其他类似的性能问题时,需要反复踩坑填坑。如何避免这种情况?

  俗话说:“工欲善其事,必先利其器”。我个人认为程序员也需要一个“利器”来定位性能问题。就像医生看病人一样,需要依靠专业的医疗工具(如X光、听诊器等)进行诊断,最终根据医生的检查结果快速准确地定位疾病的病因。工具。性能调优工具(如 perf / gprof 等)用于性能调优,就像 X 射线对患者一样。他们可以查明程序的性能瓶颈。

  但是,常用的性能调优工具如perf只能在呈现内容中列出调用栈或者非分层的时间分布,不够直观。这里推荐大家一起使用火焰图,这样会更直观的呈现perf采集等工具的数据。

  第一次认识火焰图

  Flame Graph 是由 Linux 性能优化大师 Brendan Gregg 发明的。与所有其他分析方法不同,火焰图从全局角度查看时间分布。它从下到上列出了所有可能的原因。性能瓶颈的调用栈。

  

  火焰图的整个图形看起来像一个跳动的火焰,这也是它名字的由来。

  火焰图有以下特点(这里以on-cpu火焰图为例):

  火焰图类型

  常见的火焰图类型包括 On-CPU、Off-CPU、Memory、Hot/Cold、Differential 等。它们适合处理什么样的问题?

  这里笔者主要使用了On-CPU、Off-CPU和Memory火焰图,所以这里仅对这三种火焰图进行比较,欢迎大家补充修正。

  

  火焰图分析技巧 纵轴代表调用栈的深度(栈帧数),用于表示函数之间的调用关系:下面的函数是上面函数的父函数;横轴代表调用频率,格子宽度越大,说明越可能是瓶颈;不同类型的火焰图适用于不同的优化场景。比如on-cpu火焰图适合分析CPU占用率高的问题函数,off-cpu火焰图适合解决阻塞和锁抢占问题;无意义的东西:水平顺序是为了聚合,与函数之间的依赖或调用关系无关;火焰图的各种颜色是为了便于区分,没有特殊含义;更多实践:进行性能优化,有意识地使用火焰图进行性能调优(如果时间充裕);如何绘制火焰图?

  要生成火焰图,必须有一个方便的动态跟踪工具。如果操作系统是 Linux,通常是 perf 或 systemtap 之一。其中,perf 是比较常用的。大多数Linux都收录perf,可以直接使用;SystemTap功能更强大,监控更灵活。关于如何使用perf绘制火焰图,网上有很多丰富的资料,所以本文以SystemTap为例。

  SystemTap 是一个动态跟踪工具。它采用探测机制获取内核或应用的采集运行信息,让您无需修改​​内核和应用的代码即可获取丰富的信息,帮助您分析定位。解决问题。SystemTap 定义了类似的 DSL 脚本语言,方便用户根据需要自由扩展。但是,与动态跟踪的鼻祖 DTrace 不同,SystemTap 没有驻留在内核中的运行时。它需要将脚本编译成内核模块,然后插入内核执行。这也会导致 SystemTap 启动缓慢并依赖于完整的调试符号表。

  使用SystemTap绘制火焰图的主要过程如下:

  本文演示的步骤将基于操作系统Tlinux 2.2(Linux内核版本3.10.107)

  安装 SystemTap 和操作系统符号调试表

  使用 yum 工具安装 systemtap:

  yum install systemtap systemtap-runtime

  因为systemtap工具依赖完整的调试符号表,生产环境不同机器的内核版本不同(虽然都是Tlinux2.2个版本,但是内核版本后面的次要版本不同,可以使用uname -a命令查看)所以我们还需要安装kernel-debuginfo包和kernel-devel包。我这里已经安装了这两个依赖包。

  kernel-devel-3.10.107-1-tlinux2-0046.x86_64

kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64

  根据需要绘制的火焰图类型和流程类型选择合适的脚本

  使用 SystemTap 进行统计,往往需要根据其语法编写脚本,具有一定的门槛。好在github上的spring兄(agentzh)开源了他常用的两套SystemTap脚本:openresty-systemtap-toolkit和stapxx。这两个工具集可以覆盖大部分C进程、nginx进程、Openresty进程的性能问题场景。.

  这里需要绘制off-cpu火焰图,所以使用sample-bt-off-cpu脚本

  生成内核模块

  现在我们有了统计脚本并安装了systemtap,就可以正常使用了,但是因为systemtap通过生成内核模块来采集相关探针的统计信息,所以tlinux需要所有运行的内核模块先到达。tlinux平台签名可以运行,所以:

  所以需要先修改off-cpu脚本生成内核模块;然后对内核模块进行签名;最后使用systemtap命令手动运行脚本统计监控数据。

  Systemtap的执行过程如下:

  

  所以这里我们修改off-cpu stap脚本,让它只运行到第四阶段,只生成一个内核模块

  // 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段

open my $in, "|stap -p4 --skip-badvars --all-modules -x $pid -d '$exec_path' --ldd $d_so_args $stap_args -"

or die "Cannot run stap: $!\n";

  修改后运行脚本,会生成一个内核模块

  // -p 8682 是需要监控的进程的进程号

// -t 30 是指会采样30秒

./sample-bt-off-cpu -p 8692 -t 30

  生成的内核模块名称类似于 stap_xxxxx.ko 模块名称。由于读者不需要关心内核模块签名,因此跳过该章节

  运行内核模块统计信息

  内核模块签名后,可以使用staprun命令手动运行相关内核模块

  命令:

  // 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)

staprun -x {进程号} {内核模块名} > demo.bt

  值得注意的是,被监控的进程必须有一定的load systemtap才能采集获取相关数据,即在采集的时候,同时需要一定量的请求时间(一般是自己构造请求,强调过程))

  将统计数据转换为火焰图

  获取统计数据demo.bt后,可以使用火焰图工具绘制火焰图

  下载火焰图,链接:

  命令:

  ./stackcollapse-stap.pl demo.bt > demo.folded

./flamegraph.pl demo.folded > demo.svg

  这样就得到了off-cpu火焰图:

  

  看图说话

  趁热打铁,通过几张火焰图熟悉如何使用火焰图

  图片来自春哥微博或我最近画的表演火焰图

  On-cpu 火焰图 Apache APISIX QPS 急剧下降

  

  Apache APISIX 是一个开源的国产高性能 API 网关。在之前的选型和压测中发现,当Route与场景不匹配时,QPS急剧下降,其CPU(四十八核)占用率几乎达到100%。QPS只有几千。通过绘制火焰图发现,耗时主要在表插入阶段(lj_cf_table_insert)。分析代码发现该表没有发布。每次匹配不匹配时,都会将路由发送到一个表中进行统计。往表中插入一条数据导致表越来越大,后续插入时间过长导致QPS下降。

  Off-cpu火焰图nginx互斥问题

  

  这是一个 nginx 的 off-cpu 火焰图。我们可以快速锁定到 ngx_common_set_cache_fs_size -> ngx_shmtx_lock -> sem_wait。这个逻辑使用了互斥锁,它允许nginx进程将大部分等待时间花在获取锁上。

  代理监控和报告断点问题

  

  这是代理的 CPU 外火焰图。它是一个多线程异步事件模型。主线程处理每条消息,多个线程负责配置下发或监控上报。目前的问题是监控上报性能较差,无法在周期(一分钟)内完成监控数据上报,导致出现监控断点。通过off-cpu火焰图,我们可以分析报告线程花费大量时间使用curl_easy_perform接口发送和接收http监控数据消息。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线