2 个关注者

性能优化

有很多因素会影响 Web 应用程序的性能。有些是环境因素,有些与您的代码有关,还有一些与 Yii 本身有关。在本节中,我们将列举大多数这些因素,并解释如何通过调整这些因素来提高应用程序性能。

优化您的 PHP 环境

一个配置良好的 PHP 环境非常重要。为了获得最佳性能,

  • 使用最新的稳定 PHP 版本。PHP 的主要版本可能会带来显著的性能提升。
  • 使用 Opcache(PHP 5.5 或更高版本)或 APC(PHP 5.4)启用字节码缓存。字节码缓存避免了每次请求都花费在解析和包含 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 自动加载器用于包含大多数第三方类文件,因此您应该考虑通过执行以下命令对其进行优化:

composer dumpautoload -o

此外,您还可以考虑使用 权威类映射APCu 缓存。请注意,这两种优化可能适合也可能不适合您的特定情况。

离线处理数据

当请求涉及一些资源密集型操作时,您应该考虑如何以离线模式执行这些操作,而无需用户等待它们完成。

离线处理数据有两种方法:拉取和推送。

在拉取方法中,每当请求涉及一些复杂的操作时,您都会创建一个任务并将其保存到持久存储中,例如数据库。然后,您使用单独的进程(例如 cron 作业)来拉取任务并处理它们。这种方法易于实现,但有一些缺点。例如,任务进程需要定期从任务存储中拉取。如果拉取频率太低,任务可能会延迟很长时间才被处理,但如果频率太高,则会引入高开销。

在推送方法中,您将使用消息队列(例如 RabbitMQ、ActiveMQ、Amazon SQS 等)来管理任务。每当在队列中放入一个新任务时,它就会启动或通知任务处理进程以触发任务处理。

性能分析

您应该分析您的代码以找出性能瓶颈并采取适当的措施。以下性能分析工具可能会有用:

为应用程序准备扩展

当其他方法都无济于事时,您可以尝试使您的应用程序可扩展。在 为自动扩展堆栈配置 Yii 2 应用程序 中提供了很好的介绍。

发现错别字或您认为此页面需要改进?
在 github 上编辑它 !