加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

长PHP脚本运行多次

发布时间:2020-12-13 22:13:30 所属栏目:PHP教程 来源:网络整理
导读:我有一个产品数据库,可以在早上与产品数据同步. 这个过程非常清楚: 通过查询从数据库中获取所有产品 遍历所有产品,并通过product_id从其他服务器获取和xml 从xml更新数据 将更改记录到文件. 如果我查询少量商品,但将其限制为500个随机商品,一切都很顺利.但
我有一个产品数据库,可以在早上与产品数据同步.

这个过程非常清楚:

>通过查询从数据库中获取所有产品
>遍历所有产品,并通过product_id从其他服务器获取和xml
>从xml更新数据
>将更改记录到文件.

如果我查询少量商品,但将其限制为500个随机商品,一切都很顺利.但是当我查询所有产品时,我的脚本SOMETIMES继续使用fritz并开始多次循环.几个小时后,我仍然看到我的日志文件在增长,产品正在增加.

我查看了我能想到的一切,例如:

>变量是否未使用两次而没有相互覆盖
>该函数是否自行调用
>是否也会出现少量产品:没有.
>使用cronjob调用脚本,设置正常. (是)

使其特别奇怪的原因是它有时是正确的,有时它不会.这可能是一些记忆问题吗?

编辑
wget -q -O / dev / null http://example.eu/xxxxx/cron.php?operation=sync在webmin中调用特定的小时和分钟

代码长达数百行……

谢谢

解决方法

你有:

> max_execution_time已禁用.只要需要,您的脚本将不会在该过程完成之前结束.
> memory_limit已禁用.内存中存储的数据量没有限制.

完成500条记录没有问题.这表明脚本在下一次cronjob迭代之前完成其过程.例如,如果您的cron每小时运行一次,则会在不到一小时的时间内处理500条记录.

如果您有一个将要处理大量记录的cronjob,那么请考虑向该进程添加锁定机制.仅允许脚本运行一次,并在上一个过程完成时重新启动.

在执行php脚本之前,您可以将脚本锁创建为shell脚本的一部分.或者,如果您无法访问服务器,则可以在php脚本中使用数据库锁定,如下所示.

class ProductCronJob
{
    protected $lockValue;

    public function run()
    {
        // Obtain a lock
        if ($this->obtainLock()) {
            // Run your script if you have valid lock
            $this->syncProducts();

            // Release the lock on complete
            $this->releaseLock();
        }
    }

    protected function syncProducts()
    {
        // your long running script
    }

    protected function obtainLock()
    {
        $time = new DateTime;
        $timestamp = $time->getTimestamp();
        $this->lockValue = $timestamp . '_syncProducts';

        $db = JFactory::getDbo();

        $lock = [
            'lock'         => $this->lockValue,'timemodified' => $timestamp
        ];
        // lock = '0' indicate that the cronjob is not active.
        // Update #__cronlock set lock = '',timemodified = '' where name = 'syncProducts' and lock = '0'
//        $result = $db->updateObject('#__cronlock',$lock,'id');

//        $lock = SELECT * FROM #__cronlock where name = 'syncProducts';

        if ($lock !== false && (string)$lock !== (string)$this->lockValue) {
            // Currently there is an active process - can't start a new one

            return false;

            // You can return false as above or add extra logic as below

            // Check the current lock age - how long its been running for
//            $diff = $timestamp - $lock['timemodified'];
//            if ($diff >= 25200) {
//                // The current script is active for 7 hours.
//                // You can change 25200 to any number of seconds you want.
//                // Here you can send notification email to site administrator.
//                // ...
//            }
        }

        return true;
    }

    protected function releaseLock()
    {
        // Update #__cronlock set lock = '0' where name = 'syncProducts'
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读