【问题标题】:PHP scripts in cron jobs are double processingcron 作业中的 PHP 脚本是双重处理
【发布时间】:2013-08-03 09:14:52
【问题描述】:

我有 5 个运行 PHP 文件的 cron 作业。 PHP 文件检查 MySQL 数据库中需要处理的项目。由于 cron 会同时启动所有脚本,因此某些项目似乎被处理了两次,甚至有时多达五次。

在其中一个脚本中选择文件后,它会立即发送一个 UPDATE 查询,这样其他作业就不会再次运行它。但看起来它仍然是双重处理。

如何防止其他脚本处理之前由其他 cron 作业选择的项目?

【问题讨论】:

  • 把所有东西都放在一个 crob 工作中?确保每个 cron 作业执行一项作业,这样就不可能在同一行上执行相同的操作?
  • 处理一项需要时间。大约 30 秒。如果我有五个 cron 作业,则在 30 秒内处理五个项目。

标签: php mysql cron


【解决方案1】:

此问题称为“竞争条件”。在这种情况下,这是因为 SELECT 和 UPDATE 虽然一个接一个地被调用,但并不是一个单一的操作。因此,有可能两个作业执行 SELECT 同一个作业,然后首先执行 UPDATE,然后再执行 UPDATE。所以他们继续同时运行这项工作。

不过,有一种解决方法。 您可以在表中添加一个字段,其中包含当前 cron 作业工作者的 ID(如果您在一台机器上运行它,它可能是 PID)。在工作人员中,您首先执行 UPDATE,尝试为其保留工作:

UPDATE jobs 
    SET worker = $PID, status = 'processing' 
    WHERE worker IS NULL AND status = 'awaiting' LIMIT 1

然后您确认您已成功为该工作人员预留了工作:

SELECT * FROM jobs WHERE worker = $PID

如果它没有返回你一行,这意味着其他工人首先保留它。您可以从第 1 步再试一次以获取另一份工作。如果它确实返回了一行,则进行所有处理,然后最后进行最终更新:

UPDATE jobs 
    SET status = 'done', worker = NULL
    WHERE id = $JOB_ID

【讨论】:

    【解决方案2】:

    我认为你有一个使用信号量的典型问题。看看这篇文章:

    http://www.re-cycledair.com/php-dark-arts-semaphores

    这个想法首先是每个脚本,请求相同的信号量,然后等到它空闲。然后在执行此操作时选择并更新数据库,释放信号量并开始该过程。这是唯一可以确保只有一个脚本正在读取数据库,而另一个脚本正在写入数据库的唯一方法。

    【讨论】:

      【解决方案3】:

      我会重新开始。这个思路:

      处理一件物品需要时间。大约 30 秒。如果我有五个 cron 作业,则在 30 秒内处理五个项目

      这是完全错误的,您不应该在编写代码时考虑到这一点。

      按照这个逻辑,为什么不做 100 个 cron 作业并每 30 秒做 100 个呢?回答,因为你的服务器不是RoadRunner,它会翻倒失败。

      你应该

      1. 重新考虑您的问题,这是最重要的,因为它有助于解决 1 和 2。
      2. 优化您的代码,使其不需要 30 秒。
      3. 对您的代码进行分段,以便每个作业一次只执行一项任务,这将使其更快,并确保您不会获得这种“双重处理”效果。

      编辑

      即使知道这在第三方服务器上的新知识,我的逻辑仍然成立,不要启动您无法控制的多个调用,事实上这现在更加重要。

      如果您不知道他们对这些调用做了什么,那么您就无法确定它们的顺序是否正确,何时或是否处理它们。因此,只需拨打一个电话,以确保您不会得到双重处理。

      技术解决方案是让他们缩短处理时间或让您缓存响应 - 但这可能与您的情况无关。

      【讨论】:

      • 每个作业都连接到需要时间来处理一个项目的服务器。这就是为什么需要 30 秒。作业连接的服务器不是我们的工作,它需要 4-5 次 HTTP 调用才能最终处理一项。
      • 应该把它放在你原来的问题中吗?它相当重要。答案已更新,逻辑仍然成立。
      • 这并不能真正解决问题。我们不能在 30 秒内只处理一个请求。我们正在连接的服务器(虽然处理请求非常慢),允许同时处理多个请求。然后“何时或是否处理它们”在处理后由服务器返回。是的,缓存与这种情况无关,因为我们将动态内容发送到服务器。
      • 那么您需要@klkvsk 的回答,尽管更新您的问题,以便它询问有关第 3 方服务器的正确问题。没有那个金块,还有更多的问题/答案
      猜你喜欢
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 1970-01-01
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多