猿问

laravel - 在队列完成所有作业后运行任务

我需要为一个可以达到数千个项目的列表运行一个任务。


为了避免长时间运行单个作业,我创建了一个作业来对所有项目进行排队。


问题是我需要在该队列完成之前和之后运行另一个任务。


我看到的解决方案是使用延迟:


$schedule->job(new \App\Jobs\PauseSystem())     ->hourly('00:01');

$schedule->job(new \App\Jobs\EnqueueAllItems()) ->hourly('00:02'); // adds all items as separated job in a queue

$schedule->job(new \App\Jobs\ReopenSystem())    ->hourly('55:00');

这样我就有时间00:02确保55:00所有项目都已完成。


它看起来不安全,可能会导致工作重叠。


在队列完成所有作业后,有没有更安全的方法来运行任务?


白猪掌柜的
浏览 119回答 1
1回答

智慧大石

既然你提到有并行和多个作业,下面是我们解决类似问题的方法。我们有一个报告系统来准备来自多个客户的报告。有超过1000名客户。每个ReportPusher工作负责一个客户在这项工作中,我们从不同的数据库获取报告并将所有数据推送到存储桶(redis 列表)。如果所有工作(有时是 99% 的工作)都完成工作,另一个ReportCollector工作应该完成它的工作。从单个存储桶中获取所有数据、格式化、创建 excel 并发送电子邮件。- 此收集器作业必须在所有ReportPusher作业完成后运行。我们是怎么做的;ReportPusher同时触发所有作业在某个地方设置触发作业的总数(例如 redis 键)$totaln分钟后触发ReportCollector(可能是15分钟)每个ReportPusher作业在完成其过程时都会增加另一个键$incremented15分钟后ReportCollector工作时,做这些;如果total等于incremented count让 ReportCollector 起作用如果不是,则以 t 延迟(由您决定)+ 增加尝试触发相同的作业在 n 次尝试(您决定)之后,如果计数仍然不匹配(我上面提到的 %99),则计算报告。如果一个/两个客户出现错误,此回退策略是为了防止完全失败。我们不会仅仅因为一个/两个客户而丢弃所有计算数据(客户的 %99)。您可以放置一些警报/错误跟踪系统以在以后修复损坏的数据。
随时随地看视频慕课网APP
我要回答