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

时间:2020-06-12 19:15:40

标签: php laravel

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

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

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

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

YEAR    CUSTOMER_ID CHANGES
2010    2               1
2010    1               1
2011    1               1
2012    3               2

这样,我可以在$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之间留出时间来确保所有项目都已完成。

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

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

1 个答案:

答案 0 :(得分:2)

由于您提到了并行和多个作业,因此这是我们解决类似问题的方式。我们有一个报告系统来准备多个客户的报告。有超过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%的客户)。您稍后可以放置一些警报/错误跟踪系统来修复损坏的数据。