【问题标题】:Cron vs queued taskCron vs 排队任务
【发布时间】:2019-06-05 07:59:59
【问题描述】:

我的应用程序有一个带有 execution_datetime 属性的 Order 模型。我想发送一些不同的通知。例如

  • execution_datetime 减去 12 小时:通过电子邮件发送给运营商
  • execution_datetime 减去 3 小时:给客户发短信
  • execution_datetime 加 1 小时:给客户发电子邮件

以上时序不严格,可以近似;轻微的偏差是可以接受的。此外,execution_datetime 可以同时改变...

我不确定是否为此使用 cron 或排队任务。我自己的一些想法:

Cron:

  • 需要编写业务逻辑以获取适用的订单并相应地执行
  • 是否保证执行?是否应该实现某种数据库标志以指示已发送通知,然后可能获取所有未标记为某种故障安全的到期订单?

排队的任务:

  • 在创建订单时安排任务?如果是这样,假设执行时间已更改。如何修改定时任务?您需要在某个地方跟踪任务 ID?
  • 或者可能是每天大量安排适用任务的 cron 作业?

期待您的建议。

【问题讨论】:

    标签: laravel cron scheduled-tasks


    【解决方案1】:

    好问题!我对这个讨论很感兴趣。让我用我个人经历的一个场景来插话。

    在我的应用程序中,我有一个 Listing 模型,它们有一个 promotion_ends_at 列。显然,上市促销有时会在未来结束。

    所以,正如您也提到的,有两种方法可以做到这一点。

    1. 创建列表后,我可以排队等待将来在列表中结束促销的工作)。该工作的延迟将是促销活动必须结束的时间(我可能需要几个月的时间)。
    2. 我还可以有一个定期运行的 cron 作业来管理他们的促销活动应在特定日期结束的列表。

    我们使用SQS 作为我们的队列服务,因为SQS 的最大延迟是 15 分钟,所以选项 1 不可行。然后,我们搬到了 Redis,在那里我们可以轻松地将延迟的作业排入队列。

    但是,正如您所说,promotion_ends_at 列可能会在此期间更新。因此,要么,您必须跟踪作业以使其出队,或者您可以重新检查作业在即将执行时是否仍应运行。

    例如,您可以fresh() 模型并检查您的条件是否仍然有效。就我而言,我会fresh 我的Listing 并检查promotion_ends_at 是否在过去。但是,这意味着我们将有很多陈旧的工作可能会被丢弃

    我们最终采用了一个简单的 cron 作业,它可以在需要运行的那一天大规模安排作业。我还认为运行延迟作业是一种业务逻辑,也许队列不应该对将来运行延迟太多的作业负责。

    【讨论】:

    • 听起来确实是一个类似的场景。感谢您的参与。