背景
因业务需要,定期导入Excel表格转换为数组批量入库;当一次性导入达到近千条时,有超时风险(过慢的反应时间,客户也是不接受的)
实现
创建任务
$ php artisan make:job ProcessExcel
传递变量到构造函数,后续在handle
中处理,handle
中也可注入依赖类随时调用
app/Jobs/ProcessExcel.php
class ProcessExcel implements ShouldQueue, ShouldBeUnique
{
/**
* Create a new job instance.
* @params 传递的参数
* @return void
*/
public function __construct(array $row)
{
$this->row = $row;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(SomeServices $services)
{
extract($this->row); // use params
// do somethings
}
在env中我们选择redis驱动
QUEUE_CONNECTION=redis
业务代码示例
ProcessExcel::dispatch($row); // 分发队列
// $services->store($row); // 摒弃services的操作
宝塔安装Supervisor,新增守护进程命令如下,启动用户使用www
/www/server/php/73/bin/php artisan queue:work --daemon
另外我们也可以适当有一些监控
app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
/* 队列处理开始 */
Queue::before(function (JobProcessing $event) {
// $event->connectionName
// $event->job
// $event->job->payload()
$payload = $event->job->payload();
/*
'payload' =>
array (
'uuid' => '7fc971b7-3d3d-4476-a47d-04bcbae6ac31',
'timeout' => 10, // 执行超时时间
'id' => 'M2IPb87k4hHKlWPOtfRszOmKci2xJP6J',
'backoff' => NULL, // 执行异常后重试前延迟的分钟数
'displayName' => 'App\\Jobs\\ProcessExcel', // 用于展示的别名 使用@displayName()设置
'maxTries' => 3, // 最大尝试次数
'failOnTimeout' => false, // 超时后标记为失败
'maxExceptions' => NULL, // 失败前允许的最大未处理异常数
'retryUntil' => 1655276931, // 尝试截止时间 设置为当天 次日则不再尝试当天失败任务
'job' => 'Illuminate\\Queue\\CallQueuedHandler@call',
'data' =>
array (
'command' => 'O:21:"App\\Jobs\\ProcessExcel":14:{s:7:"timeout";i:10;s:5:"tries";i:3;s:28:"' . "\0" . 'App\\Jobs\\ProcessExcel' . "\0" . 'batch";O:45:"Illuminate\\Contracts\\Database\\ModelIdentifier":4:{s:5:"class";s:23:"App\\Models\\ReportsBatch";s:2:"id";i:174;s:9:"relations";a:0:{}s:10:"connection";s:5:"mysql";}s:34:"' . "\0" . 'App\\Jobs\\ProcessExcel' . "\0" . 'report_path";s:56:"/www/wwwroot/blfy.sz17it.com/storage/app/public/reports/";s:3:"job";N;s:10:"connection";N;s:5:"queue";N;s:15:"chainConnection";N;s:10:"chainQueue";N;s:19:"chainCatchCallbacks";N;s:5:"delay";N;s:11:"afterCommit";N;s:10:"middleware";a:0:{}s:7:"chained";a:0:{}}',
'commandName' => 'App\\Jobs\\ProcessExcel',
), // 命令的详细
'attempts' => 2, // 执行次数
)
*/
});
/* 队列处理结束 */
Queue::after(function (JobProcessed $event) {
// $event->connectionName
// $event->job
// $event->job->payload()
});
}
同样支持数据表的日志记录(只保存失败记录)
php artisan queue:failed-table
其他
十分好用,客户上传表格后,无需等待处理。
以上为简单实现,有其他个性化需求可以详细查看官方文档;
参考资料
本文由 ben 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jun 16, 2022 at 10:31 am