如何将php cronjob分成几部分

时间:2018-01-27 19:52:10

标签: php

有一个PHP脚本。它从外部API获取数据并导入(更新/删除)数据到WordPress数据库(Woocommerce的产品)。有很多产品......要导入所有这些产品,脚本需要大约2-3个小时。

问题是当脚本执行时,内存不会被清除,导致溢出。之后,脚本只是默默地死掉而没有任何错误。

简而言之,脚本如下所示:

$currentMemory > 100Mb

这个想法是将cronjob脚本分成几部分:if {{1}}然后停止脚本并再次运行它,但不是从一开始就运行它,从它停止的那一刻开始。

如何实现这一目标?如果服务器有限制:每2小时只有1个cronjob脚本。

还有其他想法吗?

3 个答案:

答案 0 :(得分:2)

您可以使用Gearman等工具创建队列和工作人员以导入流程。您可以对每个工作程序进行编程,以处理一定数量的产品,这些产品所需的时间少于服务器的最长执行时间。

Gearman还允许您控制可以同时运行的工人数量。因此,导入过程会更快,并且您将确保服务器资源不被工作人员完全消耗。

答案 1 :(得分:2)

$ currentMemory>时可以对$ products数组进行serilize。 100Mb到一个文件,然后再次执行脚本:

$limit = 100*1000*1000;
$store  = 'products.bin';
$products = [];

if ( !file_exists($store)) {
    $products = getProductsFromApi();    
} else {
    $products = unserialize(file_get_contents($store));
}

foreach ($products as $key => $product) {
    $this->import($product);
    unset($products[$key]);
    if (memory_get_usage() > $limit) {
        file_put_contents($store,serialize($products));
        exec('nohup /usr/bin/php -f myscript.php');
        exit(1);
    }    
}
unlink ($store);

答案 2 :(得分:1)

您可以使用睡眠功能

例如

  $products = getProductsFromApi();
    $i=0;
    foreach ($products as $key => $product) {
    // you can use your condition here instead of this 
    if($i%10==0){// run ten times then sleep for 100 second    
sleep(100);
    }
        $this->import($product);
    $i++;
    }

https://php.net/manual/en/function.sleep.php