知识卡片

火焰图:不修改代码、不重启服务的应用无感知线上性能定位方法

普通读书笔记卡

内容

线上服务出现CPU占用100%这类性能异常时,一个常见但代价很高的排查方式是加日志、改代码、重启服务去复现和定位——但这种做法本身可能改变问题现场,甚至因为重启而让问题暂时消失、错失定位良机。火焰图提供了一种”应用无感知”的排查思路:不需要修改代码、不需要重启服务,通过对运行中进程的采样数据进行整理,以一种更直观的可视化方式展示各部分代码的资源占用情况——图中颜色的深浅本身没有特殊含义,真正该关注的是那些”平坦的山峰”,这些区域往往就是性能瓶颈所在。案例中提到,即使某段代码从逻辑上看并没有明显会引起热循环的地方,用专门针对LuaJIT的lj-lua-bt工具生成的on-CPU火焰图,也曾定位出一个真实的CPU 100%问题——原因是某个异常的请求包会卡住正则表达式解析,如果没有这类工具,这种问题在代码审查中几乎不可能被发现。除了on-CPU火焰图定位”CPU在忙着执行什么”,还有off-CPU火焰图专门用来定位那些不那么明显的”卡顿”——即进程虽然没有占满CPU,但被某种阻塞(系统信号量锁、阻塞的I/O系统调用)拖住的具体位置。这个工具组合提示了一条排查线上疑难问题的通用思路:面对无法在开发环境稳定复现、又不能承受”改代码、重启”这种排查代价的线上问题,应当优先寻找能够在不打扰运行现场的前提下采样和可视化系统实际行为的工具,把排查建立在对真实运行状态的观测之上,而不是靠猜测代码逻辑或事后加日志复现。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.11 OpenResty的现在和未来"节,"2.11.5 OpenResty中的测试和调试"(源文件:_epub-src/OEBPS/Text/Chapter2_11_6.xhtml) - 结论依据:原文说明"为了不破坏这个环境,我们希望不修改代码、不重启服务,做应用无感知的调试……我们需要关心的是平坦的山峰,那里一般是性能瓶颈所在",并举出正则表达式卡住的CPU 100%真实案例,直接支撑本卡片结论。 - 原始内容:为了不破坏这个环境,我们希望不修改代码、不重启服务,做应用无感知的调试……我们需要关心的是平坦的山峰,那里一般是性能瓶颈所在……使用lj-lua-bt后发现终端一个异常的请求包,会卡住正则表达式的解析。如果没有这类工具,会非常难以发现。