当前位置: 首页 > 后端技术 > PHP

PHP多进程任务spatie-async扩展使用说明

时间:2023-03-30 00:21:22 PHP

spatie/async是基于PCNTL扩展为PHP开发的,可以使用多进程处理任务。项目地址spatie/async一般使用示例对象形式useSpatie\Async\Pool;$pool=Pool::create()//选择执行PHP->withBinary('/path/to/php')//可以同时运行最大进程数->concurrency(20)//最大时间(以秒为单位)一个进程完成所需要的,支持小数位以实现更细粒度的超时->timeout(15)//配置应该使用哪个autoloadAutoloadersubprocess->autoload(__DIR__.'/../../vendor/autoload.php')//配置在重新检查进程状态之前循环应该休眠多长时间(以微秒为单位)。->sleepTime(50000);foreach($thingsas$thing){$pool->add(function()use($thing){//添加任务})->then(function($output){//任务回调函数执行后,返回的结果会作为变量注入到回调函数中终止后继续使用需要重新创建})->catch(function(MyException$e){//捕获异常})->catch(function(Exception$e){///捕获异常,支持不捕获做多个})->timeout(function(){//超时处理});}$pool->wait();函数用法使用Spatie\Async\Pool;$pool=Pool::create();foreach(range(1,5)as$i){$pool[]=async(function(){usleep(random_int(10,1000)));返回2;})->then(function(int$output){echo$output.PHP_EOL;});}await($pool);任务类use方法需要创建任务类并继承类Spatie\Async\Task,任务执行会调用任务类的run()方法useSpatie\Async\Task;classMyTaskextendsTask{publicfunctionconfigure(){//加载配置,如:依赖容器、核心类加载}publicfunctionrun(){//taskworker程序}}//添加task到池$pool=Pool::create();$pool->add(newMyTask());$pool->wait();补充:在Laravel中使用注意,如果没有加载bootstrap/app.php配置,则不能使用Laravel提供的类方法例如:使用Illuminate\Support\Facades\Log时会报异常Exception:Afacaderoothasnotbeensetbootstrap/app.phpisnotloadedExample'useLog','msg'=>'bootstrap/app.phpnotloaded','datetime'=>$datetime]);}}报错信息如下[2022-03-2817:26:17]local.ERROR:EmployTask{"msg":"Afacaderoothasnotbeenset.#0/www/wwwroot/laravel/app/任务/EmployTask.php(23):Illuminate\\Support\\Facades\\Facade::__callStatic()#1/www/wwwroot/laravel/app/Task/EmployTask.php(17):App\\Task\\EmployTask->test()#2/www/wwwroot/laravel/vendor/spatie/async/src/Task.php(15):App\\Task\\EmployTask->run()#3/www/wwwroot/laravel/vendor/spatie/async/src/Runtime/ChildRuntime.php(26):Spatie\\Async\\Task->__invoke()#4{main}"}加载bootstrap/app.php示例make(\Illuminate\Contracts\Console\Kernel::class);$kernel->bootstrap();}publicfunctionrun(){$datetime=date('Y-m-dH:i:s');Log::error('EmployTask',['type'=>'useLog','msg'=>'加载bootstrap/app.php','datetime'=>$datetime]);}}//也可以这样使用$pool[]=async(function()use($result,$syncemployRepository){$app=require__DIR__.'/../../../../bootstrap/app.php';$kernel=$app->make(\Illuminate\Contracts\Console\Kernel::class);$kernel->bootstrap();//任务代码})->then(function($output)use($pool){$pool->stop();})->catch(function(Exception$e){Log::error('createauth_sync',['消息'=>$e->getMessage()]);});日志如下[2022-03-2817:28:26]local.ERROR:EmployTask{"type":"useLog","msg":"Loadbootstrap/app.php","datetime":"2022-03-2817:28:26"}作者在文档中解释说,除了使用闭包,您还可以使用Task。在您需要在子进程中进行更多设置工作的情况下,任务很有用。因为子进程总是从无到有,所以您可能想要初始化,例如。执行任务之前的依赖容器。Task类使这更容易做到。package,也可以使用Task任务,用户可能需要在子进程中加载??更多的设置。子进程总是从头开始,所以需要初始化。例如:加载依赖容器、核心类)