有很多因素会影响 Web 应用程序的性能。有些是环境因素,有些与您的代码有关,还有一些与 Yii 本身有关。在本节中,我们将列举大多数这些因素,并解释如何通过调整这些因素来提高应用程序性能。
一个配置良好的 PHP 环境非常重要。为了获得最佳性能,
realpath()
缓存.在生产环境中运行应用程序时,您应该禁用调试模式。Yii 使用名为 YII_DEBUG
的常量的值来指示是否应启用调试模式。启用调试模式时,Yii 将花费额外的时间来生成和记录调试信息。
您可以在 入口脚本 的开头添加以下代码行来禁用调试模式
defined('YII_DEBUG') or define('YII_DEBUG', false);
提示:
YII_DEBUG
的默认值为false
。因此,如果您确定没有在应用程序代码中的其他地方更改其默认值,则可以简单地删除上面的行来禁用调试模式。
您可以使用各种缓存技术来显著提高应用程序的性能。例如,如果您的应用程序允许用户以 Markdown 格式输入文本,您可以考虑缓存解析后的 Markdown 内容,以避免在每次请求中重复解析相同的 Markdown 文本。请参考 缓存 部分,了解 Yii 提供的缓存支持。
模式缓存是一个特殊的缓存功能,只要您使用 活动记录,就应该启用它。如您所知,活动记录足够智能,可以检测到有关 DB 表的模式信息(例如,列名、列类型、约束),而无需您手动描述它们。活动记录通过执行额外的 SQL 查询来获取此信息。通过启用模式缓存,检索到的模式信息将保存在缓存中,并在将来的请求中重复使用。
要启用模式缓存,请配置一个用于存储模式信息的 cache
应用程序组件,并在 应用程序配置 中将 yii\db\Connection::$enableSchemaCache 设置为 true
return [
// ...
'components' => [
// ...
'cache' => [
'class' => 'yii\caching\FileCache',
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydatabase',
'username' => 'root',
'password' => '',
'enableSchemaCache' => true,
// Duration of schema cache.
'schemaCacheDuration' => 3600,
// Name of the cache component used to store schema information
'schemaCache' => 'cache',
],
],
];
复杂的网页通常包含许多 CSS 和/或 JavaScript 资产文件。为了减少 HTTP 请求的数量和这些资产的总下载大小,您应该考虑将它们合并到一个文件中并进行压缩。这可能会大大改善页面加载时间并减少服务器负载。有关更多详细信息,请参考 资产 部分。
默认情况下,会话数据存储在文件中。实现是将一个文件从打开会话锁定到它被 session_write_close()
(在 Yii 中可以作为 Yii::$app->session->close()
完成)或在请求结束时关闭为止。当会话文件被锁定时,所有尝试使用相同会话的其他请求都会被阻塞,即等待初始请求释放会话文件。这对开发和可能的小型项目来说是不错的选择。但是,在处理大量的并发请求时,最好使用更复杂的存储,例如数据库。Yii 支持各种开箱即用的会话存储。您可以通过在 应用程序配置 中配置 session
组件来使用这些存储,如下所示:
return [
// ...
'components' => [
'session' => [
'class' => 'yii\web\DbSession',
// Set the following if you want to use DB component other than
// default 'db'.
// 'db' => 'mydb',
// To override default session table, set the following
// 'sessionTable' => 'my_session',
],
],
];
上面的配置使用数据库表来存储会话数据。默认情况下,它将使用 db
应用程序组件作为数据库连接并将会话数据存储在 session
表中。但是,您必须预先创建 session
表,如下所示:
CREATE TABLE session (
id CHAR(40) NOT NULL PRIMARY KEY,
expire INTEGER,
data BLOB
)
您也可以使用 yii\web\CacheSession 将会话数据存储在缓存中。理论上,您可以使用任何支持的 缓存存储。但是请注意,一些缓存存储在存储限制达到时可能会清除缓存数据。因此,您应该主要使用那些不强制执行存储限制的缓存存储。
如果您在服务器上安装了 Redis,强烈建议您使用 yii\redis\Session 将其用作会话存储。
执行数据库查询和从数据库获取数据通常是 Web 应用程序中的主要性能瓶颈。尽管使用 数据缓存 技术可以缓解性能下降,但它并不能完全解决问题。当数据库包含大量数据并且缓存数据无效时,在没有适当的数据库和查询设计的情况下,获取最新数据可能会非常昂贵。
提高数据库查询性能的一般技术是为需要过滤的表列创建索引。例如,如果您需要按 username
查找用户记录,则应该在 username
上创建索引。请注意,虽然索引可以使 SELECT 查询速度快得多,但它会减慢 INSERT、UPDATE 和 DELETE 查询的速度。
对于复杂的数据库查询,建议您创建数据库视图以节省查询解析和准备时间。
最后但并非最不重要的一点,在 SELECT
查询中使用 LIMIT
。这可以避免从数据库中获取过多的数据并耗尽分配给 PHP 的内存。
虽然 Active Record 使用起来非常方便,但在您需要从数据库中检索大量数据时,它不像使用普通数组那样高效。在这种情况下,您可能需要考虑在使用 Active Record 查询数据时调用 asArray()
,以便检索到的数据以数组的形式表示,而不是笨重的 Active Record 对象。例如:
class PostController extends Controller
{
public function actionIndex()
{
$posts = Post::find()->limit(100)->asArray()->all();
return $this->render('index', ['posts' => $posts]);
}
}
在上面的代码中,$posts
将被填充为一个表行数组。每行都是一个普通数组。要访问第 i 行的 title
列,可以使用表达式 $posts[$i]['title']
。
您也可以使用 DAO 来构建查询并以普通数组的形式检索数据。
由于 Composer 自动加载器用于包含大多数第三方类文件,因此您应该考虑通过执行以下命令对其进行优化:
composer dumpautoload -o
此外,您还可以考虑使用 权威类映射 和 APCu 缓存。请注意,这两种优化可能适合也可能不适合您的特定情况。
当请求涉及一些资源密集型操作时,您应该考虑如何以离线模式执行这些操作,而无需用户等待它们完成。
离线处理数据有两种方法:拉取和推送。
在拉取方法中,每当请求涉及一些复杂的操作时,您都会创建一个任务并将其保存到持久存储中,例如数据库。然后,您使用单独的进程(例如 cron 作业)来拉取任务并处理它们。这种方法易于实现,但有一些缺点。例如,任务进程需要定期从任务存储中拉取。如果拉取频率太低,任务可能会延迟很长时间才被处理,但如果频率太高,则会引入高开销。
在推送方法中,您将使用消息队列(例如 RabbitMQ、ActiveMQ、Amazon SQS 等)来管理任务。每当在队列中放入一个新任务时,它就会启动或通知任务处理进程以触发任务处理。
您应该分析您的代码以找出性能瓶颈并采取适当的措施。以下性能分析工具可能会有用:
当其他方法都无济于事时,您可以尝试使您的应用程序可扩展。在 为自动扩展堆栈配置 Yii 2 应用程序 中提供了很好的介绍。
发现错别字或您认为此页面需要改进?
在 github 上编辑它 !
注册 或 登录 以发表评论。