我需要为一个可以达到数千个项目的列表运行一个任务。为了避免长时间运行单个作业,我创建了一个作业来对所有项目进行排队。问题是我需要在该队列完成之前和之后运行另一个任务。我看到的解决方案是使用延迟:$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所有项目都已完成。它看起来不安全,可能会导致工作重叠。在队列完成所有作业后,有没有更安全的方法来运行任务?
1 回答
智慧大石
TA贡献1946条经验 获得超3个赞
既然你提到有并行和多个作业,下面是我们解决类似问题的方法。我们有一个报告系统来准备来自多个客户的报告。有超过1000名客户。
每个
ReportPusher
工作负责一个客户在这项工作中,我们从不同的数据库获取报告并将所有数据推送到存储桶(redis 列表)。
如果所有工作(有时是 99% 的工作)都完成工作,另一个
ReportCollector
工作应该完成它的工作。从单个存储桶中获取所有数据、格式化、创建 excel 并发送电子邮件。- 此收集器作业必须在所有
ReportPusher
作业完成后运行。
我们是怎么做的;
ReportPusher
同时触发所有作业在某个地方设置触发作业的总数(例如 redis 键)
$total
n分钟后触发
ReportCollector
(可能是15分钟)每个
ReportPusher
作业在完成其过程时都会增加另一个键$incremented
15分钟后
ReportCollector
工作时,做这些;如果
total
等于incremented count
让 ReportCollector 起作用如果不是,则以 t 延迟(由您决定)+ 增加尝试触发相同的作业
在 n 次尝试(您决定)之后,如果计数仍然不匹配(我上面提到的 %99),则计算报告。
如果一个/两个客户出现错误,此回退策略是为了防止完全失败。我们不会仅仅因为一个/两个客户而丢弃所有计算数据(客户的 %99)。您可以放置一些警报/错误跟踪系统以在以后修复损坏的数据。
- 1 回答
- 0 关注
- 118 浏览
添加回答
举报
0/150
提交
取消