介绍LaravelOctane通过使用强大的应用程序服务器(Swoole和RoadRunner)来增强应用程序的性能。Octane引导您的应用程序一次并将其保存在内存中,然后以超音速提供请求。官方地址安装可以通过Composer包管理器安装Octane:composerrequirelaravel/octane安装好Octane后,可以执行octane:installArtisan命令,将Octane的配置文件安装到你的应用中:phpartisanoctane:install安装条件PHP8+laravelv.8.37+RoadRunnerRoadRunner由使用Go构建的RoadRunner二进制文件提供支持。当您首次启动基于RoadRunner的Octane服务器时,Octane将为您下载并安装RoadRunner二进制文件。RoadRunnerViaLaravelSailRoadRunner可用于查看原文。Swooleinstallpeclinstallswoole启动你的服务你可以通过octane:startArtisan命令启动Octane服务器。默认情况下,此命令将使用服务器应用程序Octane配置文件中指定的配置选项服务器:phpartisanoctane:start设置应用程序HTTPS。配置OCTANE_HTTPS=false设置容器启动服务OCTANE_SERVER=swoole应用代码热加载phpartisanoctane:start--watch注意使用该命令前,需要确保本地安装了Node服务。您应该在项目中安装Chokidar文件监视库:library:npminstall--save-devchokidar您可以使用监视应用程序的config/octane.php配置文件中的配置选项来配置应监视哪些目录和文件。指定工作进程数默认情况下,Octane将为计算机可用的每个CPU内核启动一个应用程序请求工作进程。然后,这些工作人员将在进入您的应用程序时用于处理传入的HTTP请求。您可以在调用octane:start命令时通过--workers选项手动指定要使用的worker数量:phpartisanoctane:start--workers=4如果您使用的是Swoole应用服务器,您还可以指定“tasks"启动worker数量:phpartisanoctane:start--workers=4--task-workers=6指定最大请求数phpartisanoctane:start--max-requests=250服务重启可以使用下面的octane:reload命令正常工作重启Octane服务器的applicationworker。通常,这应该在部署之后完成,以便将新部署的代码加载到内存中并用于处理后续请求:phpartisanoctane:reloadServicestop您可以使用octane:stopArtisan命令停止Octane服务器:phpartisanoctane:stop查看服务状态phpartisanoctane:statusOctane依赖注入由于Octane引导您的应用程序一次并在处理请求时将其保存在内存中,因此在构建您的应用程序时应考虑一些注意事项。例如,您的应用程序服务提供商的registerandboot方法仅在请求启动器最初启动时执行一次。在后续请求中,相同的应用程序实例将被重用。因此,在将应用程序服务容器或请求注入任何对象的构造函数时应格外小心。因此,该对象可能具有旧版本的容器或后续请求中的请求。Octane将自动处理请求之间任何第一方框架状态的重置。然而,Octane并不总是知道如何重置应用程序创建的全局状态。因此,您应该知道如何以Octane友好的方式构建应用程序。下面,我们将讨论使用Octane时可能导致问题的最常见情况。容器注入通常,您应该避免将应用程序服务容器或HTTP请求实例注入到其他对象的构造函数中。例如,以下绑定将整个应用程序服务容器注入到作为单例绑定的对象中:useApp\Service;/***注册任何应用程序服务。**@returnvoid*/publicfunctionregister(){$this->app->singleton(Service::class,function($app){returnnewService($app);});
在这个例如,如果Service解析实例,容器将被注入到服务中,Service实例将在后续请求中保留容器。对于您的特定应用程序,这可能不是问题;但是,它可能会导致容器意外丢失在引导周期后期或后续请求中添加的绑定。作为解决方法,您可以停止将绑定注册为单例,或者将容器解析器闭包注入始终解析当前容器实例的服务:
useApp\Service;useIlluminate\Container\Container;$this->app->bind(Service::class,function($app){returnnewService($app);});$this->app->singleton(Service::class,function(){returnnewService(fn()=>Container::getInstance());});全局应用程序助手和Container::getInstance()方法将始终返回最新版本的应用程序容器。请求注入通常,您应该避免将应用程序服务容器或HTTP请求实例注入到其他对象的构造函数中。例如,以下绑定将整个请求实例注入到绑定为单例的对象中:useApp\Service;/***注册任何应用程序服务。**@returnvoid*/publicfunctionregister(){$this->app->singleton(Service::class,function($app){returnnewService($app['request']);});}在这个例子中,如果Service实例在应用程序启动时被解析,HTTP请求就会被注入到Service中,Service实例会为后续的请求保留相同的请求。因此,所有标头、输入和查询字符串数据以及所有其他请求数据都将不正确。作为解决方法,您可以停止将绑定注册为单例,或者可以将请求解析器闭包注入到始终解析当前请求实例的服务中。或者,最推荐的方法只是将对象在运行时需要的特定请求信息传递给对象的方法之一:使用App\Service;$this->app->bind(Service::class,function($app){returnnewService($app['request']);});$this->app->singleton(Service::class,function($app){returnnewService(fn()=>$app['request']);});//或者...$service->method($request->input('name'));全局请求助手将始终返回应用程序当前正在处理的请求,因此您可以安全地在应用程序中使用。配置文件注入通常,您应该避免将配置实例注入到其他对象的构造函数中。例如,以下绑定将配置注入到作为单例绑定的对象中:useApp\Service;/***注册任何应用程序服务。**@returnvoid*/publicfunctionregister(){$this->app->singleton(Service::class,function($app){returnnewService($app->make('config'));});}在此示例中,如果配置值在请求之间更改,服务将无法访问新值,因为它依赖于原始存储库实例。作为解决方法,您可以停止将绑定注册为单例,或者可以将配置存储库解析器闭包注入到类中:useApp\Service;useIlluminate\Container\Container;$this->app->bind(Service::class,function($app){returnnewService($app->make('config'));});$this->app->singleton(Service::class,function(){returnnewService(fn()=>Container::getInstance()->make('config'));});全局配置将始终返回最新版本的配置,因此在您的应用程序中使用是安全的。管理内存泄漏请记住,Octane在两次请求之间将您的应用程序保存在内存中;因此,向静态维护的数组中添加数据会导致内存泄漏。例如,下面的控制器存在内存泄漏,因为对应用程序的每个请求都会不断向静态$data数组添加数据:seApp\Service;useIlluminate\Http\Request;useIlluminate\Support\Str;/***处理传入的请求。**@param\Illuminate\Http\Request$request*@returnvoid*/publicfunctionindex(Request$request){Service::$data[]=Str::random(10);//...}并发任务提示该功能需要使用Swoole使用Swoole时,可以通过轻量级的后台任务同时进行操作。您可以使用Octane::tickconcurrently方法执行此操作。您可以将此方法与PHP数组解构相结合以检索每个操作的结果:useApp\User;useApp\Server;useLaravel\Octane\Facades\Octane;[$users,$servers]=Octane::concurrently([fn()=>User::all(),fn()=>Server::all(),]);Octane处理的并发任务利用了Swoole的“taskworker”,Incoming请求在一个完全不同的进程中执行。可用于处理并发任务的工作人员数量由--task-workers命令上的octane:start指令决定:phpartisanoctane:start--workers=4--task-workers=6timer&intervalhintsrequiredforthis特性使用Swoole使用Swoole时,您可以注册一个“滴答”动作,该动作将每隔指定的秒数执行一次。您可以通过tick方法注册一个“tick”回调。提供给tick方法的第一个参数应该是表示代码名称的字符串。第二个参数应该是一个可调用的,将在指定的时间间隔调用。在这个例子中,我们将注册一个每10秒调用一次的闭包。通常,应在启动应用程序的服务提供者之一的方法中调用tick:Octane::tick('simple-ticker',fn()=>ray('Ticking...'))->seconds(10);使用immediate方法,您可以指示Octane在Octane服务器最初启动时立即调用tick回调,此后每N秒调用一次:Octane::tick('simple-ticker',fn()=>ray('Ticking...'))->seconds(10)->immediate();Octane缓存该功能依赖于[Swoole]()使用Swoole时,可以利用Octane缓存驱动,它提供高达每秒200万次的读写速度。因此,此缓存驱动程序是需要缓存层具有极高读/写速度的应用程序的绝佳选择。此缓存驱动程序由Swoole表提供支持。存储在缓存中的所有数据都可供服务器上的所有工作人员使用。但是重启服务器后,缓存的数据会被刷新:Cache::store('octane')->put('framework','Laravel',30);cacheinterval除了Laravel缓存系统提供的典型方法外,Octane缓存驱动也有基于interval的缓存。这些缓存将以指定的时间间隔自动刷新,并且应该使用您的应用程序服务提供商之一的引导方法进行注册。例如,以下缓存将每五秒刷新一次:useIlluminate\Support\Str;Cache::store('octane')->interval('random',function(){returnStr::random(10);},seconds:5)进程间共享内存(表)在使用Swoole时,可以定义自己任意的Swoole表并与之交互。Swoole表提供了极高的性能吞吐量,服务器上的所有worker都可以访问这些表中的数据。但是,当服务器重新启动时,其中的数据将丢失。表应该在表应用程序的Octane配置文件的配置数组中定义。已为您配置了一个最多允许1000行的示例表。字符串列的最大大小可以通过在列类型之后指定列大小来配置,如下所示:'tables'=>['example:1000'=>['name'=>'string:1000','votes'=>'int',]],要访问表,可以使用以下Octane::table方法:useLaravel\Octane\Facades\Octane;Octane::table('example')->set('uuid',['name'=>'NunoMaduro','votes'=>1000,]);返回Octane::table('example')->get('uuid');Swoole表支持的列类型:string、int、float。翻译地址