【问题标题】:Stop executing cron job on specific condition在特定条件下停止执行 cron 作业
【发布时间】:2019-12-17 08:26:59
【问题描述】:

我有一个包含 2 个表的数据库:

subscribers:
 _____________________________
|  id    |  name  |   email   |
|________|________|___________|
|  1     |  John  |   e@m.com |
|  ..    |   ..   |     ..    |
|  5000  |  Mark  |   c@b.com |
|________|________|___________|
last_id:
 _______
|  id   |
|_______|
| NULL  |
|_______|

我每天运行一个 cron 作业来一次发送所有电子邮件,但是 脚本在 100 秒后超时

所以我想每次发送大约 200 封电子邮件:

/* Get the id from last time is script was executed */
$last_id = "SELECT `id` FROM `last_id`";

/* Select the next 200 subscribers starting from the last id */
$query= "SELECT * FROM `subscribers` WHERE `id` > ". $last_id . " LIMIT 200";

/* Send 200 emails */
..

/* Get the last id of these 200 subscribers */
$last = ;

/* Update the value of `id` in `last_id` table */
$query= "UPDATE `last_id` SET `id` = ". $last;

cron 作业每 10 分钟运行一次此脚本,但在发送完所有电子邮件后,脚本将一遍又一遍地执行,而不会发送任何电子邮件。

那么如何在发送完所有邮件后停止执行这个 cron 作业,当last_id = 5000 并在第二天重新开始?

【问题讨论】:

  • 您可以直接将 10 分钟的暂停“构建”到您的 php 脚本中:每天运行一次,每次循环发送 200 封邮件,然后等待 10 分钟。或者,您可以检查是否已到达表的末尾并在数据库中的某处放置一个状态(例如 last_id = -1),然后让另一个 cron 每天将其重置为 0
  • 暂停 10 分钟,您的意思是使用 sleep(600)?
  • 是的,你也可以unset()sleep()之前的内存消耗变量,一旦你到达表的末尾,你可以在第二天将last_id重置为0跨度>
  • “那么如何在发送完所有电子邮件后停止执行这个 cron 作业并在第二天重新启动它?” 你在这里尝试优化什么?不要浪费时间思考/编程优化具有空表选择的 cronjob,它一开始就快速点亮。思考/编程的时间并不能证明可能几毫秒的性能增益。当 PHP 看到表为空时,脚本可能会使用 returnexit(0)
  • @RaymondNijland,那么您有什么建议作为替代方案?

标签: php mysql shell cron


【解决方案1】:

我们曾经在学校做过这样的练习,我们通过在订阅者表中添加“发送日期”列来对其进行排序。您选择限制 X 和日期

如果全部发送,查询将不会选择任何内容。所以 cron 会运行但什么也不做。

第二天,它将重新开始,因为选择将返回“未发送”记录。

如果您不想使用日期,可以使用 bool 或 tinyint,选择 'send' 为 0 的位置,发送后将其设置为 1。并让另一个 cron 将所有记录更新回 0,每天运行一次/或您想要发送这些电子邮件的任何增量。

【讨论】:

  • cron 作业是每 x 分钟执行一次还是每天执行一次?
  • 每 X 分钟。
猜你喜欢
  • 2022-10-19
  • 2016-12-17
  • 2011-05-25
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
相关资源
最近更新 更多