在本教程中,我们将展示如何用 OpenResty XRay 定量分析 PHP Laravel 应用中 CPU 时间的消耗情况。我们将展示其中占用 CPU 最多的那些 PHP 代码路径,这些热代码路径是 OpenResty XRay 自动分析和解释 PHP 语言级别的 CPU 火焰图获得的。OpenResty XRay 是真正的非侵入式动态分析,无需在目标应用中安装任何特殊模块或插件,无需重新编译目标应用,甚至无需重启已经在运行的进程。

问题:高 CPU 使用率

我们用 PHP 的 Laravel 框架搭建了一个简单的 “hello world” Web 应用。

Screenshot

在这里定义了一个请求处理函数,它会返回一个 “Hello, world” 的响应。

Screenshot

使用 curl 命令访问 Laravel 的 HTTP 接口。响应体确实是 “hello world”。

Screenshot

运行 top 命令来检查目标 PHP 进程的 CPU 使用情况。

这是之前展示过的 PHP “hello world” 服务进程。

Screenshot

我们事先使用客户端压测工具将 CPU 使用率压满到 100%。

Screenshot

运行 ps 命令来查看这个进程的详情。

这个 php 二进制可执行文件是 Linux 发行版自带的。

Screenshot

使用引导式分析功能分析 Laravel 应用中的 CPU 分布情况

接下来,我们使用 OpenResty XRay 来查看 CPU 时间是如何分布在 PHP 进程内部的所有代码路径上的。在浏览器中打开 OpenResty XRay 的 Web 控制台。

Screenshot

确保我们当前分析的是正确的机器。

Screenshot

如果当前显示的机器不对,您可以从下面的列表中选择正确的。

Screenshot

进入 “Guided Analysis” 页面。

Screenshot

这里可以看到系统能分析的不同类型的问题。

Screenshot

让我们选择 “High CPU Usage”。

Screenshot

点击 “Next”。

Screenshot

选择之前的 PHP 应用实例。

Screenshot

选择消耗接近 100% CPU 资源的进程。也就是我们之前在 top 中看到的。

Screenshot

确保应用的类型是正确的。通常默认值就是对的。

Screenshot

OpenResty XRay 可以在多种不同语言的级别上进行分析。这里保持 PHP 和 C/C++ 都选中。

Screenshot

我们还可以设置最长的分析时间。这里保持默认的 300 秒不变。

Screenshot

开始分析。

Screenshot

系统将持续进行多轮分析,现在它正在运行第一轮。

Screenshot

第一轮已经完成,现在进入第二轮分析。对这个例子来说,运行一轮就够了。

Screenshot

现在停止分析。

Screenshot

可以看到自动生成了一份分析报告。

Screenshot

这是现在我们要分析的问题类型,CPU。

Screenshot

这是 CPU 资源消耗最高的 C 代码路径。

Screenshot

第一个 zend_execute 函数用于解释和执行 PHP 操作码。

Screenshot

当服务器收到一个新的 HTTP 请求时,php_cli_server_dispatch_router 函数会被调用来读取和解析请求数据。

Screenshot

main 函数表明这是一个由 PHP CLI 启动的内置 Web 服务器。

Screenshot

点击查看更多细节。

Screenshot

这条热代码路径是由这个 C 语言级别的 CPU 火焰图自动推导出来的。

Screenshot

下面是对问题更详细的解释和建议。它提到了我们之前看到的 zend_execute 函数。

Screenshot

让我们看看最热 PHP 代码路径的细节。

Screenshot

bootProvider 函数是 Laravel 框架的一部分,该函数负责启动应用注册的 Service Provider。

Screenshot

点击 “More” 查看细节。

Screenshot

点击这个图标放大。

Screenshot

继续放大。

Screenshot

Laravel 的 ServiceProvider 程序中,ServiceProvider::boot 方法用于为 Carbon 日期库注册宏和配置。相应的 boot 方法用于初始化时区等设置。

Screenshot

IgnitionServiceProvider::boot 函数为 Laravel 应用提供调试页面的错误页面做初始化。

Screenshot

让我们看看第二热 PHP 代码路径,它消耗了接近 14% 的 CPU 时间。

Screenshot

这个 register 函数会在应用引导过程中被调用,它是 Service Provider 程序注册过程的一部分。在 Laravel 中,每次请求时都会启动一个新的应用实例。

Screenshot

点击 “More” 查看细节。

Screenshot

放大火焰图。

Screenshot

继续放大。

Screenshot

resolveProvider 是 Laravel 框架中的一个方法,用于解析和注册Service Providers。

Screenshot

DatabaseServiceProvider::register 方法在 Laravel 中负责向服务容器注册数据库服务及其相关组件。

Screenshot

第三热的代码路径消耗了大约 13% 的 CPU 时间。

Screenshot

看一下这条代码路径的细节。

Screenshot

该代码路径用于发送 HTTP 响应,它是 “hello world” 响应的实现。

Screenshot

第一条代码路径和第二条路径虽然不是同一个服务,但是类似。

Screenshot

这是 Laravel 和 OpenResty 的性能对比图。可以看到 Laravel 的性能比 OpenResty 低了两个数量级。OpenResty 框架在设计和实现更加高效和先进。

Screenshot

全自动分析报告

您可以在 “Insights” 页面中找到以日和周为周期的报告。所以您不是非得用 “Guided Analysis” 功能。

Screenshot

当然,“Guided Analysis” 对于应用的开发和演示是很有用的。

Screenshot

关于 OpenResty XRay

OpenResty XRay 是一个动态追踪产品,它可以自动分析运行中的应用,以解决性能问题、行为问题和安全漏洞,并提供可行的建议。在底层实现上,OpenResty XRay 由我们的 Y 语言 驱动,可以在不同环境下支持多种不同的运行时,如 Stap+、eBPF+、GDB 和 ODB。

关于作者

章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。

章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,并编写过 60 多个开源软件库。

关注我们

如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

我们提供了英文版原文和中译版(本文)。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!