为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
白猪掌柜的 2023-05-26 16:10:17
我需要为一个可以达到数千个项目的列表运行一个任务。为了避免长时间运行单个作业,我创建了一个作业来对所有项目进行排队。问题是我需要在该队列完成之前和之后运行另一个任务。我看到的解决方案是使用延迟:$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)。您可以放置一些警报/错误跟踪系统以在以后修复损坏的数据。


查看完整回答
反对 回复 2023-05-26
  • 1 回答
  • 0 关注
  • 81 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信