【问题标题】:How do I stop concurrent PHP scripts from executing the same code at the same time?如何阻止并发 PHP 脚本同时执行相同的代码?
【发布时间】:2014-01-17 11:02:17
【问题描述】:

我使用的货币汇率服务每月只允许 1000 个请求,因此我必须将检索到的汇率保存到数据库中一小时,然后再用新请求更新它们。

然而,我的网站请求新汇率的频率远高于每小时一次,我终于意识到这是因为并发 PHP 脚本试图同时将汇率更新到数据库中。这是我的代码的简化示例:

function get_rates()
{
    $rates = get_transient( 'exchange_rates' );
    if( $rates === false ) {

        $ch = curl_init( 'http://examplecurrencyrates.com/rates.json' );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
        $rates = curl_exec( $ch );

        $cache_time = 3600; // 60 mins
        set_transient( 'exchange_rates', $rates, $cache_time );

        curl_close( $ch );
    }
    return $rates
}

如何确保每小时只有一个请求更新汇率?

【问题讨论】:

  • 您可以专门编写一个脚本来更新您使用计划任务运行它的速率,传递一个关键参数或其他东西以确保只有任务运行它而不是通过其他方式运行
  • 你可以在服务器上写一个小文件,包含上次更新的日期和时间。每次脚本要更新时,您都会读取文件,如果没有小时差,则退出脚本。

标签: php wordpress curl concurrency


【解决方案1】:

我建议使用 cronjobs(或任何其他作业调度程序),通过每小时运行一次脚本来更新费率。 您每月有 720 小时,因此您不会超过每月 1000 小时的限制。

【讨论】:

  • 这是个好主意,但我的代码在插件中使用,并且会有多人使用它。他们希望它通过简单地激活它来工作,要求他们设置一个 cronjob 不会顺利进行。
  • 好的,你可以看到 Ryan 建议使用一些“锁” - 但你可以改进它,使其至少被锁定一个小时(在锁定文件中存储最后一次的时间戳您更新数据,如果自上次更新以来已经超过一个小时 - 再次检索数据。)祝你好运! :)
【解决方案2】:

我在类似但略有不同的场景中使用的一种方法是锁定文件。

在我的示例中,我有一个每分钟运行一次的脚本。如果此脚本在某次运行中有大量处理工作,则可能需要 3 分钟 - 在这段时间内,我不希望该脚本的另外 2 个实例运行并尝试执行相同的工作。

所以我做的是在进程开始时,创建一个锁文件,例如:

$lock_file = fopen('/lock_file_directory/my_script.lock', 'w');
fclose($lock_file);

在脚本的最后,后处理,我添加以下内容:

unlink('/lock_file_directory/my_script.lock');

这样,在脚本的处理过程中,锁文件始终存在。

现在让这个工作,在脚本的开头 - 添加:

if(file_exists('/lock_file_directory/my_script.lock')) { exit; }

这意味着如果锁定文件存在,下一个实例将不会运行。

【讨论】:

    【解决方案3】:

    你应该像使用 MySQL 表

    CREATE TABLE IF NOT EXISTS `running` (
      `script` varchar(255) NOT NULL,
      PRIMARY KEY (`script`)
    ) ENGINE=InnoDB; 
    

    在启动脚本时尝试此查询

    INSERT INTO running ('myscript');
    

    如果有任何已经在运行它第二个死

    在脚本结束时做

    DELETE FROM running WHERE script = 'myscript' LIMIT 1;
    

    【讨论】:

      猜你喜欢
      • 2015-11-01
      • 2011-01-27
      • 2022-09-23
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多