darkghosthunter / laraload
Requires
- php: ^7.4.3||^8.0.2
- darkghosthunter/preloader: ^2.2.0
- illuminate/events: ^6.0||^7.0||^8.0
- illuminate/http: ^6.0||^7.0||^8.0
- illuminate/support: ^6.0||^7.0||^8.0
- symfony/finder: ^4.3||^5.0
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/canvas: ^4.0||^5.0||^6.0
- orchestra/testbench: ^4.1||^5.0||^6.0
- phpunit/phpunit: ^9.3
README
请迁移到新包。
Laraload
轻松为您的 Laravel 项目创建 PHP 预加载脚本。
要求
- Laravel 6.x, 7.x 或 8.x (Lumen 可能 也能使用)
- PHP 7.4.3, PHP 8.0 或更高版本
ext-opcache
此包不强制要求 Opcache 扩展。只需确保在项目的主 PHP 进程中启用它即可。
安装
调用 composer 即可完成。
composer require darkghosthunter/laraload
什么是预加载?这是做什么的?
预加载是 PHP 的一个新功能。它将文件列表“编译”到内存中,从而使应用程序代码运行得更快而不需要预热。为此,它需要在进程启动时读取一个“上传”这些文件的 PHP 脚本。
这允许第一个请求避免冷启动,此时所有脚本都必须由 PHP 在那一刻加载。由于此步骤被移至进程启动时,第一个请求因此变得更快,因为所有需要的脚本都已经位于内存中。
此包封装了生成预加载文件的预加载包。一旦生成,您可以将生成的列表指向您的 php.ini
opcache.preload = 'www/app/storage/preload.php';
之后,下一次 PHP 启动时,此文件列表将被预加载。
使用方法
默认情况下,此包会在 storage/preload.php
中每 500 个请求不断重新创建您的预加载脚本。就是这样。但您想了解细节,对吧?
- 一个全局可终止的中介检查是否存在非错误响应。
- 然后它调用一个自定义的 Condition 类。
- 如果 Condition 评估结果为
true
,则生成预加载脚本。 - 使用生成状态触发
PreloadCalledEvent
。
配置
有些人可能不会对“默认”行为感到满意。幸运的是,您可以配置自己的方式来生成脚本。
首先发布配置文件
php artisan vendor:publish --provider="DarkGhostHunter\Laraload\LaraloadServiceProvider"
让我们检查配置数组
<?php return [ 'enable' => env('LARALOAD_ENABLE'), 'condition' => \DarkGhostHunter\Laraload\Conditions\CountRequests::class, 'output' => storage_path('preload.php'), 'memory' => 32, 'use_require' => false, 'autoload' => base_path('vendor/autoload.php'), 'ignore-not-found' => true, ];
启用
<?php return [ 'enable' => env('LARALOAD_ENABLE'), ];
默认情况下,Laraload 会在生产环境中自动启用。您可以使用设置为 true
或 false
的环境变量强制启用或禁用它。
LARALOAD_ENABLE=true
条件
<?php return [ 'condition' => 'App\MyCustomCondition@handle', ];
此包附带一个简单的条件类,该类在每 500 个请求时返回 true
,从而触发脚本的生成。
您可以为生成预加载脚本定义自己的条件类。这将在请求处理完毕后由浏览器调用,并由服务容器解决。
条件的调用方式与控制器操作相同:作为可调用的类或使用Class@action表示法。
输出
<?php return [ 'output' => '/var/www/preloads/my_preload.php', ];
默认情况下,脚本保存在您的存储路径中,但您可以更改文件名和路径,只要PHP有写入权限即可保存。请务必检查您的文件权限。
内存限制
<?php return [ 'memory' => 64, ];
对于大多数应用程序,32MB作为预加载限制是足够的,但您可能需要根据您的特定项目对其进行微调。
方法
<?php return [ 'use_require' => true, 'autoload' => base_path('vendor/autoload.php'), ];
Opcache允许使用require_once
或opcache_compile_file()
预加载文件。
Laraload使用opcache_compile_file()
来更好地管理预加载的文件。一些未解决的链接在启动时可能会输出警告,但没有严重的问题。
使用require_once
将“执行”所有文件,在编译之前解析所有链接(导入、父类、特性、接口等),并且可能在不应执行的文件上输出严重错误。根据您的应用程序,您可能希望使用其中一个。
如果您计划使用require_once
,请确保您已设置Composer自动加载的正确路径,因为它将用于解决类以及其他文件。
忽略未找到的文件
<?php return [ 'ignore-not-found' => true, ];
从版本2.1.0开始,默认忽略不存在的文件。这可能适用于由Laravel在运行时创建并由Opcache积极缓存的文件,但在部署时不存在,例如实时外观。
您可以根据任何原因禁用此功能,如果任何文件丢失,则将抛出异常,但除非您知道自己在做什么,否则建议保持不变。
包含和排除目录
为了更好地管理,您现在可以使用包含在此包中的Symfony Finder来附加或排除目录中的文件,以获取其中的文件列表,并具有更好的过滤选项。
为此,添加一个array
目录,或注册一个接收Symfony Finder实例的回调,以进一步过滤您想要附加或排除的文件。您可以在您的App Service Provider中使用Laravel
外观(或注入Laraload)来完成此操作。
use Symfony\Component\Finder\Finder; use Illuminate\Support\ServiceProvider; use DarkGhostHunter\Laraload\Facades\Laraload; class AppServiceProvider extends ServiceProvider { // ... public function boot() { Laraload::append(function (Finder $find) { $find->in('www/app/vendor/name/package/src')->name('*.php'); }); Laraload::exclude(function (Finder $find) { $find->in('www/app/resources/views')->name('*.blade.php'); }); } }
常见问题解答(FAQ)
- 我可以禁用Laraload吗?
- 我需要重新启动我的PHP服务器来获取更改吗?
绝对需要。生成脚本是不够的,如果脚本路径为空或PHP进程本身没有完全重新启动,则PHP不会获取更改。您可以使用CRON或其他方式安排服务器重启。
- 当我使用它时,包返回错误!
检查您是否使用的是最新的PHP稳定版本(关键),并且Opcache已启用。此外,请检查您的存储目录是可写的。
作为一个安全的赌注,您可以使用位于darkghosthunter/preloader/helpers/safe-preloader.php
中的安全预加载脚本,并调试错误。
如果您确定这是一个由包引起的错误,请打开一个issue,包含完整细节和堆栈跟踪。如果这是一个由预加载本身引起的问题,请在那里提出问题。
当使用 PHP CLI 时,Opcache 不会被启用,如果启用了,它将收集错误的统计信息。您必须让实时应用程序在需要时自动生成列表。
- 这会排除包本身吗?
不会的:因为底层 Preloader 包可能不会被频繁请求,所以是否排除它并不重要。Laraload 中的文件也不会被排除在列表之外,因为这些文件是触发 Preloader 所必需的,而不会影响性能。
- 我已经激活了 Laraload,但我的应用程序仍然感觉不够 快。怎么回事?
Laraload 会创建一个预加载脚本,但 不会将脚本加载到 Opcache 中。一旦脚本被生成,您必须将其包含在您的 php.ini
文件中 - 目前没有其他方法可以做到这一点。这将只在 PHP 进程启动时生效。
如果您仍然 觉得应用程序运行缓慢,请记住对您的应用程序进行基准测试,缓存配置和视图,检查数据库查询和 API 调用,并排队执行昂贵的逻辑等。您还可以在 RoadRunner 上使用 Laravel Octane。
- 列表是如何创建的?
基本上:按访问次数降序排列的最频繁访问的文件。每个文件都会消耗内存,所以当文件达到一定的内存限制(默认为 32MB)时,列表会进行 软切割。
- 你说 "软切割",为什么是这样?
每个文件都是通过 opcache_compile_file()
加载的。如果最后一个文件是一个包含列表外链接的类,PHP 将发出一些警告,这是正常且预期的,但如果这些文件之前没有被添加,它不会编译链接的文件。
- 我可以将项目中的所有文件都放进去吗?
您不应该这样做。包含应用程序的所有文件与仅包含最常请求的文件相比,可能效果不明显。您始终可以自己基准测试应用程序以证明这对于您的情况是错误的。
- 我可以使用闭包(Closure)作为条件吗?
不,您必须使用您的默认条件类或您自己的类,或者使用 Class@method
语法。
- 我可以禁用中间件吗?或者只检查 XXX 状态?
不行。如果您需要完全控制,请直接使用 Preloader 包。
- 中间件在单元测试中工作吗?
不行。当应用程序在单元测试环境中运行时,中间件不会被注册。
- 我如何知道预加载脚本是否成功生成?
当预加载脚本被调用时,您将收到一个包含编译状态(成功为 true
,失败为 false
)的 PreloadCalledEvent
实例。您可以通过 添加监听器 来发送电子邮件或 Slack 通知。
如果存在问题,应用程序的日志记录器将捕获异常。
- 为什么我现在需要使用回调来追加/排除文件,而不是一个简单的文件数组?
这个新版本使用 Preloader 2,它为处理目录内的文件提供了更大的灵活性。这种方法与直接发出文件数组不兼容,但长期来看更方便。考虑到追加和排除文件大多需要精确度,因此决定将其保留为方法调用以提供这种灵活性。
- 我如何更改默认条件的访问次数、缓存或缓存键?
虽然我鼓励您创建自己的条件,但您可以通过在AppServiceProvider.php
文件中的register()
方法下添加一个容器事件来轻松地更改它们。
$this->app->when(\DarkGhostHunter\Laraload\Conditions\CountRequests::class) ->needs('$hits') ->give(1500);
许可证
本软件包的许可证由MIT许可证授权。