性能¶
概览¶
编写不佳的应用程序性能总是很差。开发人员提高应用程序性能的一种非常常见的方法是:
只需投入更多硬件
上述方法的问题是双重的。首先,在大多数情况下,所有者将是承担额外成本的人。第二个问题是,总会有一个时间点,无法再升级硬件,而必须求助于负载均衡器、Docker Swarm 等等,这将使成本飙升。
问题依然存在:编写不佳的应用程序
要加快您的应用程序,您首先需要确保您的应用程序以最佳方式编写以满足其需求。没有什么能比得上一个良好的设计。之后,还有许多方面需要考虑:- 服务器硬件 - 连接的客户端(位置、浏览器)- 网络延迟 - 数据库硬件
和更多。在本文中,我们将尝试突出一些情景,提供有关您的应用程序真正缓慢在哪里的更多见解。
注意
这些是建议和良好实践。您没有任何义务遵循本文档中的建议,而且此列表绝不是详尽无遗的。您的性能提升策略主要取决于您的应用程序需求。
服务器¶
性能剖析是一种动态应用分析形式,提供有关您应用程序的指标。性能剖析提供了应用程序在任何给定时间实际发生情况的真实画面,从而引导您关注应用程序需要改进的地方。性能剖析应在生产应用程序中持续进行。
它确实会带来开销,因此必须考虑到这一点。最详细的性能剖析发生在每个请求上,但这将取决于您的流量。我们当然不希望因为我们在剖析应用程序而增加服务器的负载。一种常见的性能剖析方法是每 100 个或每 1,000 个请求剖析一次。过一段时间后,您将有足够的数据来得出关于减速发生在哪里、为什么出现峰值等结论。
XDebug¶
XDebug提供了一个非常方便的内置剖析工具。您要做的就是安装扩展并在您的php.ini
:
使用像这样的工具Webgrind将允许您连接到XDebug并获取有关您的代码正在发生什么的非常有价值的信息。Webgrind提供哪些方法比其他方法更慢以及其他统计数据。
Xhprof¶
Xhprof是另一个用于剖析 PHP 应用程序的扩展。要启用它,只需在引导文件的开头添加以下行:
然后在文件的末尾保存剖析的数据:
<?php
$xhprof_data = xhprof_disable('/tmp');
$XHPROF_ROOT = '/var/www/xhprof/';
include_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_lib.php';
include_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_runs.php';
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, 'xhprof_testing');
echo "https://localhost/xhprof/xhprof_html/index.php?run={$run_id}&source=xhprof_testing\n";
Xhprof 提供了一个内置的 HTML 查看器来分析剖析的数据:
如上所述,剖析可能会增加服务器的负载。在Xhprof的情况下,您可以引入一个条件,只有在 X 个请求之后才开始剖析。
SQL 语句¶
几乎所有的 RDBMS 都提供工具来识别慢速 SQL 语句。识别和修复慢查询对于提高服务器端性能非常重要。MariaDB / MySql / AuroraDb 提供了启用slow-query
日志slow-query
日志
中。然后可以由开发团队分析日志并进行调整。my.cnf
(别忘了重启数据库服务器)
客户端¶
另一个需要关注的领域是客户端。改进诸如图像、样式表、JavaScript 文件等资源的加载可以显著提高性能并增强用户体验。有许多工具可以帮助识别客户端瓶颈:
浏览器¶
大多数现代浏览器都有工具来剖析页面加载时间。这些工具很容易调用网页检查器或开发者工具。例如,当使用 Brave 或任何基于 Chromium 的浏览器时,您可以检查页面,开发者工具将显示当前页面(文件)已加载的内容瀑布图、所需时间以及总加载时间:
提高客户端性能的一个相对简单的修复方法是为资源设置正确的头部信息,以便它们在未来过期,而不是在每次请求时从服务器加载。此外,CDN提供商可以通过从离发起请求的客户端最近的分发中心分发资源来提供帮助。
Yahoo! YSlow¶
PHP¶
建议改进方法。PHP 在每个新版本中都变得越来越快。使用最新版本可以提高应用程序的性能以及 Phalcon 的性能。
字节码缓存¶
OPcache以及其他许多字节码缓存有助于减少每次请求中读取、标记化和解析 PHP 文件的开销。解释的结果会在 RAM 中保持不变,只要 PHP 作为 fcgi (fpm) 或 mod_php 运行。OPcache 从 PHP 5.5.0 开始捆绑。要检查是否已激活,请在 php.ini 中查找以下条目:
此外,用于操作码缓存的内存量需要足够大以容纳应用程序的所有文件。默认的128MB通常足以应对即使较大的代码库。服务器端缓存¶
APCu可用于缓存计算密集型操作的结果或否则较慢的数据源(如高延迟的网络服务)的结果。什么结果可以缓存是另一个话题,但经验法则:这些操作需要频繁执行并产生相同的结果。确保通过分析测量优化确实提高了执行时间。
与前面提到的操作码缓存一样,请确保可用的RAM适合您的应用。APCu的替代品有Redis或Memcached- 尽管它们需要在服务器上或另一台机器上运行额外的进程。
慢任务¶
根据应用程序的需求,有时可能需要执行长时间运行的任务。这样的任务示例可能是处理视频、优化图像、发送电子邮件、生成PDF文档等。这些任务应使用后台作业进行处理。通常的过程是:- 应用程序通过向队列服务发送消息来启动任务 - 用户看到一条消息,表明任务已被安排 - 在后台(或其他服务器上),工作脚本查看队列 - 当消息到达时,工作脚本检测消息类型并调用相关的任务脚本 - 任务完成后,通知用户数据已准备好。
上述内容是对后台处理队列服务工作的简化视图,但可以提供关于如何执行后台任务的想法。还有各种可用的队列服务,您可以使用相关的PHP库来利用:
页面速度¶
mod_pagespeed加快您的网站速度并减少页面加载时间。这个开源的Apache HTTP服务器模块(也可用于nginx)自动将网页性能最佳实践应用于页面及其相关资产(CSS、JavaScript、图像),而无需您修改现有的内容或工作流程。