snapshotpl/preloader

从 Opcache 创建 PHP 通用预加载脚本的辅助工具。

1.3.0 2021-07-01 19:06 UTC

This package is auto-updated.

Last update: 2024-08-29 05:00:59 UTC


README

 Braden Collum - Unsplash (UL) #9HI8UJMSdZA

Latest Version on Packagist License Coverage Status

Opcache 预加载

只需一行代码,即可获得最佳选项,保持您的应用程序始终运行快速。

此包会自动从您的 Opcache 统计信息中生成 PHP 7.4 预加载脚本。无需手动修改。

如果您正在寻找预加载 Laravel 项目,请查看 Laraload

目录

安装

使用 Composer 在项目中安装此软件包

composer require darkghosthunter/preloader

此软件包不需要 ext-opcache 即可安装。只需确保在您的应用程序服务器中将其启用

用法

在任何 Opcache 已启用并运行的应用程序位置,使用您的 Composer 自动加载器路径调用 Preloader,并指定输出编译脚本的路径

<?php

use DarkGhostHunter\Preloader\Preloader;

Preloader::make()->autoload(__DIR__ . '/vendor/autoloader.php')
    ->output(__DIR__.'/preloader.php')
    ->generate();

这将自动收集 Opcache 统计信息,并生成优化的 preload.php 文件。在这种情况下,文件将在调用 Preloader 的同一目录中创建。

www
└── app
    ├── PreloaderCall.php
    └── preload.php

然后,在您的 php.ini 中告诉 PHP 在启动时使用此文件作为预加载器。

opcache.preload=/www/app/preload.php

重新启动使用 Opcache 的 PHP 进程,这就完成了。

如果您在 Opcache 禁用或无命中时使用 Preloader,将会抛出异常。

工作原理

此软件包将向 Opcache 请求有关最常请求的文件的信息。您可以在此 Medium 文章中查看有关预加载的详细信息

由于最佳统计数据是在应用程序运行一段时间后获得的,因此您可以使用自己的机制(或类提供的机制)仅在满足某些条件后编译列表。

请放心,您可以配置编译列表的内容和方式。

配置

您可以将 Preloader 配置为在满足条件时运行,限制文件列表,并指定输出编译预加载列表的位置。

when()(可选)

如果您不想使用 Opcache 命中,则可以使用 when()。当传递的变量评估为 true 时,Preloader 将继续执行,这由您控制。

Preloader::make()->when(false); // You will never run, ha ha ha!

您还可以使用返回 true 的闭包(箭头函数或任何其他可调用函数)。

Preloader::make()->when(fn () => $app->cache()->get('should_run'));

whenHits()(可选)

如果您不知道应用程序的实际负载,这是收集良好预加载列表的最好方法。

Preloader::make()->whenHits(200000); // After a given number of hits.

当命中数达到设置的数值时,列表将被生成。这将避免在应用程序运行多次之前生成预加载列表。

注意!如果您使用 overwrite(),则每次达到命中数后都会重新生成脚本!

whenOneIn()(可选)

列表将在给定的机会次数中生成一次(次数越高,运行越少)。

Preloader::make()->whenOneIn(2000); // 1 in 2,000 chances.

使用overwrite()可以与它一起使用,以便不断重新创建列表,这可能会很有用。

Preloader::make()->overwrite()->whenOneIn(2000);

memory()(可选,默认值)

Preloader::make()->memory(32);

MB中设置你的内存限制。默认的32MB对于大多数应用程序来说已经足够了。预加载器将在达到内存限制之前生成文件列表。

这考虑了Opcache中缓存的每个脚本的memory_consumption键,而不是实际文件大小。

此限制与Opcache内存限制无关。

exclude()(可选)

您可以使用exclude()排除Opcache提供的列表中的文件,它接受单个文件或文件数组。这些文件将传递给glob()方法。这些文件路径必须是**绝对路径**。

Preloader::make()->exclude([
    '/app/foo.php', 
    '/app/bar.php',
    '/app/quz/*.php'
]);

这些被排除的文件将不会包含在列表生成中,也不会计入内存限制。

预加载器库文件将自动排除。您可以使用includePreloader()禁用此功能。

Preloader::make()->includePreloader()
    ->exclude([
        '/app/foo.php', 
        '/app/bar.php',
        '/app/quz/*.php'
    ]);

append()(可选)

当然,您也可以使用绝对路径手动将文件添加到要生成的预加载脚本中。只需使用append()发出它们。这些文件将传递给glob()方法。这些文件路径必须是**绝对路径**。

Preloader::make()->append([
    '/app/foo.php', 
    '/app/bar.php',
    '/app/quz/*.php'
]);

将文件添加到开头将它们放在列表生成的**之后**,因此它们不会计入列表内存限制。

Preloader::make()->memory(64)->append('foo.bar');

任何重复添加的文件都将被忽略,因为列表在编译脚本之前会自动删除它们。

output()(必需)

我们需要知道输出脚本的位置。建议在同一个应用程序文件夹中执行此操作,因为大多数PHP进程都将能够访问同一目录内的写入。如果不是这样,您可以选择指出位置。

Preloader::make()->output(__DIR__ . '/../../my-preloader.php'); 

overwrite()(可选)

有时您可能已经运行了预加载器脚本。为了避免用另一个列表替换它,默认情况下,当检测到脚本文件已存在时,预加载器不会执行任何操作。

要更改此行为,您可以使用overwrite()方法指示预加载器始终重新写入文件。

Preloader::make()->overwrite()->generate();

注意与whenHits()when()等条件一起使用。如果条件为真,预加载器将反复覆盖预加载脚本...

shouldCompile()|shouldRequire()(可选)

默认情况下,预加载器将使用require_once将文件上传到Opcache。由于此操作会**执行**文件本身以预先解析链接,因此某些项目可能在使用此方法时遇到问题。

您可以使用shouldCompile()将其更改为使用opcache_compile_file()来更改此行为。这将读取文件,但不会解析链接,因此列表中最后的一些文件可能具有悬空链接(如 Traits、Interfaces和其他类),并且在文件被Opcache读取时可能会出现一些警告。

Preloader::make()->shouldCompile()->generate();

generate()(必需)

一旦您的预加载器配置就绪,您就可以使用generate()生成列表。

Preloader::make()->generate();

这将自动创建一个用于预加载应用程序的PHP脚本。如果成功,它将返回true,如果条件不满足或存在不应覆盖的现有预加载文件,则返回false

list()(替代方案)

或者,您可以使用list()检索文件原始列表作为数组。

Preloader::make()->list();

如果您有自己的脚本或只是想对其进行实验,这可能会很有用。

给我一个例子

好吧。假设我们有一个包含1500个文件的框架。我们不知道任何指标,所以我们将在部署一周后盲目地将尽可能多的文件推入256MB的内存中,以便它有足够的Opcache统计信息。

<?php
// index.php

require __DIR__ . '/../vendor/autoload.php';

$app = \Framework\App::make();

$response = $app->run();

$response->sendToBrowser();

// A week after deployment
$weekAfterDeploy = $app->deploymentTimestamp() + (7*24*60*60);

// If a week has passed, and no script was created, do it!
\DarkGhostHunter\Preloader\Preloader::make()
    ->when(time() > $weekAfterDeploy)
    ->autoload(__DIR__ , '/../vendor/autoload.php')
    ->memory(256) // 256MB of memory limit
    ->output(PHP_LOCALSTATEDIR . '/preload.php') // put it in /var.
    ->generate();

安全性

如果您发现任何与安全相关的问题,请通过电子邮件发送到darkghosthunter@gmail.com,而不是使用问题跟踪器。

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件