找出 PHP 代码速度变慢的地方(性能问题)
这是我在SO 的第一个问题。
我的公司有一个内部应用程序,最近被要求维护该应用程序。 该应用程序是用 PHP 构建的,其编码相当良好(OO、DB Abstraction、Smarty),没什么WTF-ish。
问题是应用程序非常慢。
我如何找出导致应用程序速度变慢的原因? 我已经优化了代码以进行很少的数据库查询,因此我知道是 PHP 代码需要一段时间才能执行。 我需要一些可以帮助我完成此任务的工具,并且需要设计一种检查代码的策略。
我可以自己完成检查/策略工作,但我需要更多 PHP 工具来找出我的应用程序出了问题的地方。
想法?
Here's my first question at SO.
I have a internal application for my company which I've been recently ask to maintain. The applications is built in PHP and its fairly well coded (OO, DB Abstraction, Smarty) nothing WTF-ish.
The problem is the applications is very slow.
How do I go about finding out what's slowing the application down? I've optimized the code to make very few DB queries, so I know that it is the PHP code which is taking a while to execute. I need to get some tools which can help me with this and need to devise a strategy for checking my code.
I can do the checking/strategy work myself, but I need more PHP tools to figure out where my app is crapping up.
Thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
有许多变量会影响应用程序的性能。 我建议您不要立即认为 PHP 是问题所在。
首先,您如何为 PHP 提供服务? 您是否尝试过 Apache 或 IIS 本身的基本优化? 服务器是否正忙于处理其他类型的请求? 您是否使用过 PHP 代码加速器? 测试服务器是否是瓶颈的一种方法是尝试在另一台服务器上运行应用程序。
其次,整个应用程序的性能是否缓慢,或者似乎只影响某些页面? 这可以告诉您从哪里开始分析性能。 如果整个应用程序速度很慢,则问题更有可能出现在底层服务器/平台中,或者出现在每个请求(例如,用户身份验证)中的全局 SQL 查询中。
第三,你提到最小化SQL查询的数量,但是优化现有的查询呢? 如果您使用 MySQL,您是否利用了每个存储系统的各种优势? 您是否对最重要的查询运行了 EXPLAIN 以确保它们是否已正确索引? 这对于访问大表的查询至关重要; 数据集越大,您就越会注意到不良索引的影响。 幸运的是,有很多文章诸如此类其中解释了如何使用EXPLAIN。
第四,一个常见的错误是假设数据库服务器将自动使用系统可用的所有资源。 您应该检查以确保已为数据库应用程序明确分配了足够的资源。 例如,在 MySQL 中,您需要为密钥缓冲区、临时表大小、线程并发、innodb 缓冲池大小等添加自定义设置(在 my.cnf 文件中)。
如果您已仔细检查了所有 设置上面的方法仍然无法找到瓶颈,像 Xdebug 这样的代码分析器绝对可以提供帮助。 就我个人而言,我更喜欢 Zend Studio 分析器,但它可能不是最佳选择,除非您已经在利用 Zend Platform 堆栈的其余部分。 然而,根据我的经验,PHP 本身是性能缓慢的根本原因的情况很少见。 通常,代码分析器可以帮助您更精确地确定哪些数据库查询是罪魁祸首。
There are many variables that can impact your application's performance. I recommend that you do not instantly assume PHP is the problem.
First, how are you serving PHP? Have you tried basic optimization of Apache or IIS itself? Is the server busy processing other kinds of requests? Have you taken advantage of a PHP code accelerator? One way to test whether the server is your bottleneck is to try running the application on another server.
Second, is performance of the entire application slow, or does it only seem to affect certain pages? This could give you an indication of where to start analyzing performance. If the entire application is slow, the problem is more likely in the underlying server/platform or with a global SQL query that is part of every request (user authentication, for example).
Third, you mentioned minimizing the number of SQL queries, but what about optimizing the existing queries? If you are using MySQL, are you taking advantage of the various strengths of each storage system? Have you run EXPLAIN on your most important queries to make sure they are properly indexed? This is critical on queries that access big tables; the larger the dataset, the more you will notice the effects of poor indexing. Luckily, there are many articles such as this one which explain how to use EXPLAIN.
Fourth, a common mistake is to assume that your database server will automatically use all of the resources available to the system. You should check to make sure you have explicitly allocated sufficient resources to your database application. In MySQL, for example, you'll want to add custom settings (in your my.cnf file) for things like key buffer, temp table size, thread concurrency, innodb buffer pool size, etc.
If you've double-checked all of the above and are still unable to find the bottleneck, a code profiler like Xdebug can definitely help. Personally, I prefer the Zend Studio profiler, but it may not be the best option unless you are already taking advantage of the rest of the Zend Platform stack. However, in my experience it is very rare that PHP itself is the root cause of slow performance. Often, a code profiler can help you determine with more precision which DB queries are to blame.
观看 Rasmus Lerdorf(PHP 创建者)的演示。 他介绍了一些测试 PHP 速度的好例子、要寻找的内容以及一些可能减慢速度的内部结构。 XDebug 是他使用的工具之一。 他还就了解框架的性能成本提出了非常扎实的观点。
视频:
http://www.archive.org/details/simple_is_hard
幻灯片(因为很难在视频):
http://talks.php.net/show/drupal08/1
Watch this presentation by Rasmus Lerdorf (creator of PHP). He goes into some good examples of testing PHP speed and what to look for as well as some internals that can slow things down. XDebug is one tool he uses. He also makes a very solid point about knowing what performance cost you're getting into with frameworks.
Video:
http://www.archive.org/details/simple_is_hard
Slides (since it's hard to see on the video):
http://talks.php.net/show/drupal08/1
正如 Juan 提到的,xDebug 非常出色。 如果您使用的是 Windows,WinCacheGrind 将允许您查看报告。
As Juan mentioned, xDebug is excellent. If you're on Windows, WinCacheGrind will let you look over the reports.
我最近在类似的情况下使用了 XDebug 分析。 它输出一份完整的配置文件报告,可以使用许多常见的配置文件应用程序读取该报告(不过不能给您一个列表,我只是使用了 slackware 附带的一个)。
I've used XDebug profiling recently in a similiar situation. It outputs a full profile report that can be read with many common profiling apps ( Can't give you a list though, I just used the one that came with slackware ).
我们使用 Zend 开发环境(Windows)。 昨天,我们通过在运行 Process Explorer 时单步执行调试器来观察每行执行时的内存/CPU/磁盘活动来解决内存使用高峰问题。
进程资源管理器:http://technet.microsoft.com/en-us/sysinternals /bb896653.aspx。
ZDE 包括一个基本的性能分析器,可以显示页面请求期间每个函数调用所花费的时间。
We use Zend Development Environment (windows). We resolved a memory usage spike yesterday by stepping through the debugger while running Process Explorer to watch the memory/cpu/disk activity as each line was executed.
Process Explorer: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx.
ZDE includes a basic performance profiler that can show time spent in each function call during page requests.
我使用 PEAR Benchmark 和 log4php。
在我想要分析的脚本顶部,我创建了一个围绕 Benchmark_Timer 对象。 在整个代码中,我添加了
$object->setMarker("name");
调用,尤其是在可疑代码周围。包装类有一个 destroy 方法,它获取日志信息并将其写入 log4php。 我通常将其发送到系统日志(许多服务器,聚合到一台服务器上的一个日志文件)。
在调试中,我可以查看日志文件并查看需要改进的地方。 稍后在生产中,我可以解析日志文件并进行性能分析。
它不是 xdebug,但它始终处于打开状态,使我能够比较代码的任意两次执行。
I use a combination of PEAR Benchmark and log4php.
At the top of scripts I want to profile I create an object that wraps around a Benchmark_Timer object. Throughout the code, I add in
$object->setMarker("name");
calls, especially around suspect code.The wrapper class has a destroy method that takes the logging information and writes it to log4php. I typically send this to syslog (many servers, aggregates to one log file on one server).
In debug, I can watch the log files and see where I need to improve things. Later on in production, I can parse the log files and do performance analysis.
It's not xdebug, but it's always on and gives me the ability to compare any two executions of the code.
如果您的服务器性能下降是导致该问题的原因,您还可以查看 HA 代理 或任何其他负载平衡解决方案应用程序处理缓慢。 服务器。
You can also look at the HA Proxy or any other load balancing solution if your server degraded performance is the cause of the application slow processing. server.
您还可以使用 APD (高级 PHP 调试器)。
让它发挥作用非常容易。
有一个很好的教程如何编译 APD 并用它进行分析:http://martinsikora。 com/compiling-apd-for-php-54
Also You could use APD (Advanced PHP Debugger).
It's quite easy to make it work.
There is a nice tutorial how to compile APD and make profiling with it : http://martinsikora.com/compiling-apd-for-php-54
您还可以尝试使用 php 中的 register_tick_function 函数。 它告诉 php 在您的代码中定期调用某个函数。 然后,您可以跟踪当前正在运行的函数以及调用之间的时间量。 然后你就可以看到什么花费了最多的时间。
http://www.php.net/register_tick_function
you can also try using the register_tick_function function in php. which tells php to call a certain function periodcally through out your code. You could then keep track of which function is currently running and the amount of time between calls. then you could see what's taking the most time.
http://www.php.net/register_tick_function
如果它有一个很大的代码库,如果你还没有尝试过 apc。
http://pecl.php.net/package/APC
ifs its a large code base try apc if you're not already.
http://pecl.php.net/package/APC
Xdebug 配置文件绝对是最佳选择。 另一个提示 - WincacheGrind 很好,但最近没有更新。 http://code.google.com/p/webgrind/ - 在浏览器中可能是一个简单快捷的替代方案。
但很可能,它仍然是数据库。 检查相关索引 - 以及它是否有足够的内存来缓存尽可能多的工作数据。
Xdebug profile is definitely the way to go. Another tip - WincacheGrind is good, but not been updated recently. http://code.google.com/p/webgrind/ - in a browser may be an easy and quick alternative.
Chances are though, it's still the database anyway. Check for relevant indexes - and that it has sufficient memory to cache as much of the working data as possible.
phpED (http://www.nusphere.com/products/phped.htm)还提供出色的调试和分析功能,以及在 PHP 代码中添加监视、断点等的能力。 集成分析器直接提供 IDE 中每个函数调用和类方法的时间细分。 浏览器插件还可以与 Firefox 或 IE 快速集成(即使用浏览器访问慢速 URL,然后单击按钮进行分析或调试)。
它对于指出应用程序速度缓慢的地方非常有用,以便集中大部分编码工作; 并且它避免浪费时间优化已经很快的代码。 在尝试过 Zend 和 Eclipse 之后,我现在对 phpED 的易用性深信不疑。
请记住,在针对网络服务器进行调试时,Xdebug 和 phpED(带有 DBG)都需要安装额外的 PHP 模块。 phpED 还提供(我未尝试过)本地调试选项。
phpED (http://www.nusphere.com/products/phped.htm) also offers great debugging and profiling, and the ability to add watches, breakpoints, etc in PHP code. The integrated profiler directly offers a time breakdown of each function call and class method from within the IDE. Browser plugins also enable quick integration with Firefox or IE (i.e. visit slow URL with browser, then click button to profile or debug).
It's been very useful in pointing out where the app is slow in order to concentrate most coding effort; and it avoids wasting time optimising already fast code. Having tried Zend and Eclipse, I've now been sold on the ease of use of phpED.
Bear in mind both Xdebug and phpED (with DBG) will require an extra PHP module installed when debugging against a webserver. phpED also offers (untried by me) a local debugging option too.