代码之家  ›  专栏  ›  技术社区  ›  Mike B

限制PHP脚本的建议/技巧

  •  7
  • Mike B  · 技术社区  · 16 年前

    我有一个定期(每小时)运行脚本的计划任务。这个脚本与数据库和文件系统进行了一些繁重的交互,并定期运行几分钟。问题是,当脚本运行时,服务器的CPU使用率会急剧上升,从而降低正常操作的速度。有没有一种方法可以限制这个过程,使它花费更长的时间,但不会消耗那么多的资源?

    我研究过PHP的不同配置选项,但似乎没有适合我需要的配置选项。

    将php.ini中的内存限制设置为较低的值会很容易导致数据对象溢出。

    我看到过类似的文章,人们建议在脚本的某些点上使用sleep(),但这并不能阻止脚本攻击服务器。

    最佳解决方案是某种方法来告诉LAMP(在本例中是WAMP)堆栈仅使用10%的最大CPU利用率。我一点也不关心运行时,如果它意味着每秒节省CPU周期的话,我更愿意花更长的时间。我的另一个解决方案是用数据库复制设置一个不同的服务器,这样cron就可以在不降低其他一切速度的情况下进城。

    环境:Windows Server 2K3、Apache 2.2.11、PHP 5.2.9、MySQL5.1

    我很欣赏对这种情况的任何洞察。

    编辑: 我很感激所有的答案,即使是那些特定于尼克斯的答案。在我的情况下,改变托管环境还为时过早。希望这个问题能帮助其他人,不管操作系统如何。

    9 回复  |  直到 16 年前
        1
  •  8
  •   pix0r    16 年前

    这是个棘手的问题。如果通过命令行运行php脚本,可以将进程的调度优先级设置为低( start /low php.exe myscript.php 我相信。如果您的PHP脚本本身实际上正在做占用您的CPU的大部分处理,那么这可能有效。但是,您说您正在进行一些繁重的数据库和文件系统交互,这个解决方案将无济于事。看起来对于插入和更新查询有一个mysql提示“低优先级”,这可能对您有所帮助,但我没有尝试过。

        2
  •  3
  •   cgp    16 年前

    You can set processes in Windows to be a lower priority. 我不确定进程是如何启动的,但是如果您将进程设置为低优先级,只要您将优先级设置为非常低,CPU资源就会得到它们。

        3
  •  3
  •   Lucacri    16 年前

    UNIX (LAMP)在继续循环之前,我通过检查服务器的负载来解决这个问题。

    function get_server_load($windows = 0) {
        $os = strtolower(PHP_OS);
        if(strpos($os, "win") === false) {
            if(file_exists("/proc/loadavg")) {
             $load = file_get_contents("/proc/loadavg");
             $load = explode(' ', $load);
             return $load;
            }
            elseif(function_exists("shell_exec")) {
             $load = explode(' ', `uptime`);
             return $load;
            }
            else {
             return "";
            }
        }
    }
    
    for(... ... ...){
        $data = get_server_load(); 
        if($data[0] < 0.2){
         // continue
        }else{
            sleep(1);
        }
    }
    

    这个功能也可以在Windows上使用,但我不能保证。在Linux上,它提供了一个带有最后1分钟、5分钟和15分钟负载的数组

    另外,考虑以较低的优先级启动脚本(如果通过CLI启动)(在Linux中,使用“nice”)。

    在继续循环之前,您还可以使用其他值,比如Apache活动进程的数量(您可以分析127.0.0.1/server_status页)。如果在httpd.conf中启用了mod_状态,或者也启用了mysql情况(活动连接?)

        4
  •  2
  •   grossvogel    16 年前

    可以更改cron条目以使用 nice ?

        5
  •  2
  •   Csaba Kétszeri    16 年前

    不是一个好主意 使用服务器为客户机服务并分析数据。

    因此,如果您正在寻找最终的解决方案,请对您的应用程序进行一些重新设计,并将数据分析从前端和实时数据库卸载到另一个专门用于此任务的系统。

    即使您能够成功地控制分析仪,它也会消耗宝贵的资源,否则将可以为用户提供服务。

        6
  •  1
  •   Ionuț G. Stan    16 年前

    这可能是一个困难的更改,但将数据结构重构为迭代器可能是值得的。另外,如果代码中有循环引用,请提供一个类似clearReferences()的方法来取消设置这些对象。这是一个在PHP5.3中解决的问题。

    如果你有:

    class Row
    {
        protected $_table;
    
        public function __construct($table)
        {
            $this->_table = $table;
        }
    }
    
    class Table
    {
        protected $_row;
    
        public function __construct()
        {
            $this->_row = new Row($this);
        }
    }
    

    向Row类添加ClearReferences()方法:

    class Row
    {
        public function clearReferences()
        {
            $this->_table = null;
        }
    }
    

    这就是我现在能想到的。

        7
  •  1
  •   scotts    16 年前

    我有一堆脚本,我用类似的方式从cron运行,使用nice:

    0****nice-n19 php myscript.php

    这不会有助于RAM的利用(只有改变脚本的编写方式才能做到这一点),但它只使用了CPU,否则CPU将处于空闲状态。

    编辑:没有看到问题涉及到Windows环境,抱歉…把这个留给任何有同样问题的*尼克斯用户。

        8
  •  1
  •   staticsan    16 年前

    也许你的剧本只是想同时做太多的事情。如果它一小时跑三次会不会少一点?

    另一个解决方案可能是为运行这种“后端”处理设置一个额外的服务器。如果它不在数据库中施加过多的负载(仅限于Web服务器),这将特别有效。

    另一种方法是看它的工作是否可以朝着不同的方向划分。这些类型的脚本通常有一些生成结果的大型SQL语句,用于生成大量的小型SQL语句。如果后者可以放在某个地方,那么可以在以后的步骤中针对数据库运行它们。这种方法还可以让您使用一个未缓冲的查询来获取预处理数据,这可以显著降低PHP代码的内存消耗。

        9
  •  0
  •   AndreasT    16 年前

    如果将它(Apache)作为服务运行,则可以更改优先级 Win Control Center/服务中的设置。 您的CPU使用率无论如何都会激增,但其他程序将是首选。 由调度程序执行。 也可以尝试将数据库/服务器放在与 应用。