성과분석이란?
성능 분석은 코드 수준에서 애플리케이션의 상대적 성능을 측정합니다. 성능 분석에서 캡처하는 이벤트에는 CPU 사용량, 메모리 사용량, 함수 호출 기간 및 횟수, 호출 그래프가 포함됩니다. 프로파일링 동작은 애플리케이션 성능에도 영향을 미칩니다.
성능 분석은 언제 수행해야 합니까?
성능 분석 수행 여부를 고려할 때 먼저 다음 사항을 질문해야 합니다. 애플리케이션에 성능 문제가 있습니까? 그렇다면 다음 사항을 추가로 고려해야 합니다. 문제가 얼마나 큰가요?
이렇게 하지 않으면 성급하게 최적화하는 함정에 빠지게 되어 시간을 낭비하게 될 수 있습니다.
애플리케이션에 성능 문제가 있는지 확인하려면 성능 목표를 결정해야 합니다. 예를 들어 동시 사용자 100명의 응답 시간은 1초 미만입니다. 그런 다음 벤치마크를 통해 이 목표를 달성했는지 확인해야 합니다. 일반적인 실수는 개발 환경에서 벤치마킹을 수행하는 것입니다. 실제로 프로덕션 환경에서 벤치마킹을 해야 합니다. (실제 생산환경 또는 시뮬레이션 생산환경, 후자는 SaaS에서 쉽게 구현 가능합니다.
ab, siege, JMeter 등 벤치마킹용 제품이 많이 있습니다. 저는 개인적으로 JMeter의 기능 세트를 선호하지만 ab와 siege가 사용하기 더 쉽습니다.
애플리케이션에 성능 문제가 있다고 판단되면 성능을 분석하고 개선 사항을 구현한 다음 다시 벤치마킹하여 문제가 해결되었는지 확인해야 합니다. 모든 변경 후에는 이를 벤치마킹하여 효과를 확인해야 합니다. 변경 사항을 많이 적용하고 애플리케이션 성능이 저하되는 것을 발견하면 어떤 변경 사항이 문제를 일으켰는지 정확히 찾아낼 수 없습니다.
다음 그림은 제가 정의한 Performance Life Cycle입니다.
성능 저하의 일반적인 원인
성능 저하의 일반적인 원인 중 일부는 매우 놀랍습니다. PHP와 같은 고급 언어를 사용하더라도 코드 품질이 문제의 원인이 되는 경우는 거의 없습니다. 오늘날의 하드웨어 구성에서는 CPU가 성능 제한의 원인이 되는 경우가 거의 없습니다. 일반적인 이유는 다음과 같습니다.
데이터 저장
외부 리소스
어떤 성능 분석기를 선택해야 할까요?
PHP에는 활성 프로파일러와 수동 프로파일러라는 두 가지 프로파일러가 있습니다.
액티브 VS 패시브 성능 분석
활성 분석기는 개발 중에 사용되며 개발자가 활성화합니다. 능동 분석기는 수동 분석기보다 더 많은 정보를 수집하며 성능에 더 큰 영향을 미칩니다. 일반적으로 활성 분석기는 프로덕션 환경에서 사용할 수 없습니다. XDebug는 활성 분석기입니다.
생산 환경에서는 능동 분석기를 사용할 수 없기 때문에 Facebook은 수동 분석기인 XHProf를 출시했습니다. XHPrf는 프로덕션 환경에서 사용하도록 제작되었습니다. 성능 문제를 진단하기 위한 충분한 정보를 수집하는 동시에 성능에 미치는 영향은 최소화됩니다. XHProf와 OneAPM은 모두 패시브 프로파일러입니다.
일반적으로 XDebug에서 수집한 추가 정보는 일반적인 성능 문제 분석에 필요하지 않습니다. 이는 개발 환경에서도 지속적인 성능 분석을 위해 패시브 프로파일러가 더 나은 선택임을 의미합니다.
XHProf XHGui
XHProf는 Facebook에서 개발했으며 성능 데이터를 보기 위한 기본 사용자 인터페이스를 포함합니다. 또한 Paul Reinheimer는 성능 데이터를 보고, 비교하고, 분석하기 위한 XHGui와 향상된 사용자 인터페이스(UI)를 개발했습니다.
설치
XHProf 설치
XHProf는 PECL을 통해 설치할 수 있습니다. 다음 단계를 따르세요.
$ pecl install xhprof-beta
pecl 명령은 php.ini 설정을 자동으로 업데이트하려고 시도합니다. pecl이 업데이트하려는 파일은 다음을 사용하여 찾을 수 있습니다:
$ pecl config-get php_ini
지정된 파일(있는 경우) 상단에 새 구성 줄을 추가합니다. 좀 더 적합한 위치로 옮기고 싶을 수도 있습니다.
확장을 컴파일한 후에는 활성화해야 합니다. 이렇게 하려면 PHP INI 파일에 다음 코드를 추가해야 합니다.
[xhprof] extension=xhprof.so
이후에는 XHGui를 이용하여 성능 분석 및 점검을 쉽게 수행할 수 있습니다.
XHGui 설치
XHGui를 설치하려면 git에서 직접 가져와야 합니다. 프로젝트는 github(https://github.com/perftools/xhgui
XHGui 요구 사항:
먼저 프로젝트를 원하는 위치에 복제하세요. Debian 기반 Linux 시스템(예: Ubuntu 등)에서는 /var/www일 수 있습니다. Mac OS X에서는 /Library/WebServer/Documents일 수 있습니다.
$ cd /var/www $ git clone https://github.com/perftools/xhgui.git $ cd xhgui $ php install.php
最后一个命令是运行 composer 以安装依赖并检查 XHGui 缓存目录的权限。如果失败,你可以手动运行 composer install。
下一步,你可能需要创建配置文件。这一步很容易实现,可以使用在 /path/to/XHGui/config/config.default.php 下的默认配置文件。
如果你在本地运行 MongoDB,没有身份验证,则可能不需要这样做。因为它将回退为默认值。而在多服务器环境中,你会需要一个所有服务器都能进行存储的远程 MongoDB 服务器,并进行恰当的配置。
为提高 MongoDB 的性能,你可以运行以下指令以添加索引:
$ mongo > use xhprof db.results.ensureIndex( { 'meta.SERVER.REQUEST_TIME' : -1 } ) db.results.ensureIndex( { 'profile.main().wt' : -1 } ) db.results.ensureIndex( { 'profile.main().mu' : -1 } ) db.results.ensureIndex( { 'profile.main().cpu' : -1 } ) db.results.ensureIndex( { 'meta.url' : 1 } )
其他配置
如果你不想在生产环境中安装 mongo ,或无法让 Web 服务器访问 mongo 服务器,您可以将性能分析数据保存在磁盘中,再导入到本地 MongoDB 供以后分析。
为此,请在 config.php 中进行以下修改:
<?php 'save.handler' = 'file', 'save.handler.filename' => '/path/to/xhgui/xhprof-' .uniqid("", true). '.dat', ?>
改变文件中的 save.handler,然后取消批注 save.handler.filename ,为其赋一个恰当的值。
注意:默认每天只保存一个分析文件。
一旦分析数据的准备就绪,你就可以使用 XHGui 附带的脚本导入之:
$php /path/to/xhgui/external/import.php /path/to/file.dat
在此之后的步骤都相同。
运行 XHGui
XHGui 是以 PHP 为基础的 Web 应用程序,你可以以 /path/to/xhgui/webroot 为根文件,设置一个标准的虚拟主机。
或者,你可以简单地使用 PHP 5.4+ cli-server 例如:
$ cd /path/to/xhgui $ php -S 0:8080 -t webroot/
运行性能分析器
运行分析器时,你需要在待分析的所有页面包含 external/header.php 脚本。为此,你可以在 PHP ini 文件设置 auto_prepend_file 。你既可以直接在公共 INI 文件进行设置,也可以限制到单一的虚拟主机。
对于 Apache 服务器,添加以下代码:
php_admin_value auto_prepend_file "/path/to/xhgui/external/header.php"
对于 Nginx 服务器,在服务器配置中添加以下代码:
fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/xhgui/external/header.php";
如果您使用 PHP 5.4+ cli-server(PHP -S),则必须通过命令行标记进行设置:
$ php -S 0:8080 -dauto_prepend_file=/path/to/xhgui/external/header.php
默认情况下,分析器运行时只分析(大约) 1% 的请求。这是由以下 external/header.php 代码控制的:
<?php if (rand(0, 100) !== 42) { return; } ?>
如果你想分析每一个请求(例如,在开发阶段),你可以将这段代码注释掉。如果你想让分析 10% 的请求,你可以做如下改动:
<?php if (rand(0, 10) !== 4) { return; } ?>
这允许你对一小部分用户请求进行分析,而不过多影响单个用户或太多用户。
如果你想在性能分析时进行手动控制,你可以这样做:
<?php if (!isset($_REQUEST['A9v3XUsnKX3aEiNsUDZzV']) && !isset($_COOKIE['A9v3XUsnKX3aEiNsUDZzV'])) { return; } else { // Remove trace of the special variable from REQUEST_URI $_SERVER['REQUEST_URI'] = str_replace(array('?A9v3XUsnKX3aEiNsUDZzV', '&A9v3XUsnKX3aEiNsUDZzV'), '', $_SERVER['REQUEST_URI']); setcookie('A9v3XUsnKX3aEiNsUDZzV', 1); } if (isset($_REQUEST['no-A9v3XUsnKX3aEiNsUDZzV'])) { setcookie('A9v3XUsnKX3aEiNsUDZzV', 0, time() - 86400); return; } ?>
这段代码会检查一个随机命名的 GET/POST/COOKIE 变量(在此例中为:A9v3XUsnKX3aEiNsUDZzV),同时创建一个同名的 Cookie ,用于分析该请求的整个过程,例如:表单提交后的重定向,Ajax 请求等等。
此外,它允许一个名为 no-A9v3XUsnKX3aEiNsUDZzV 的 GET/POST 变量来删除 Cookie ,停止分析。
当然,我们欢迎大家尝试使用 OneAPM 来为您的 PHP 和 Java 应用做免费的性能分析。OneAPM 独有的探针能够深入到所有 PHP 和 Java 应用内部完成应用性能管理和监控,包括代码级别性能问题的可见性、性能瓶颈的快速识别与追溯、真实用户体验监控、服务器监控和端到端的应用性能管理。 OneAPM 可以追溯到性能表现差的 SQL 语句 Traces 记录、性能表现差的第三方 API、Web 服务、Cache 等等。