略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: sys_getloadavg

2024-11-13

sys_getloadavg

(PHP 5 >= 5.1.3, PHP 7, PHP 8)

sys_getloadavg获取系统的负载(load average)

说明

sys_getloadavg(): array

返回三个系统负载(系统运行队列中的进程数)的样本数据,分别是1分钟、5分钟和15分钟之前。

返回值

返回一个包含1分钟、5分钟和15分钟之前采样数据的array

范例

示例 #1 sys_getloadavg() 的例子

<?php
$load 
sys_getloadavg();
if (
$load[0] > 80) {
    
header('HTTP/1.1 503 Too busy, try again later');
    die(
'Server too busy. Please try again later.');
}
?>

注释

注意: 此函数未在 Windows 平台下实现。

add a noteadd a note

User Contributed Notes 12 notes

up
34
stanislav dot eckert at vizson dot de
6 years ago
Function to get current CPU load as percentage value under Windows and Linux.

Note: Function is getServerLoad(). It will return a decimal value as percentage of current CPU load or NULL if something went wrong (e. g. insufficient access rights).

<?php

    header
("Content-Type: text/plain");

    function
_getServerLoadLinuxData()
    {
        if (
is_readable("/proc/stat"))
        {
           
$stats = @file_get_contents("/proc/stat");

            if (
$stats !== false)
            {
               
// Remove double spaces to make it easier to extract values with explode()
               
$stats = preg_replace("/[[:blank:]]+/", " ", $stats);

               
// Separate lines
               
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
               
$stats = explode("\n", $stats);

               
// Separate values and find line for main CPU load
               
foreach ($stats as $statLine)
                {
                   
$statLineData = explode(" ", trim($statLine));

                   
// Found!
                   
if
                    (
                        (
count($statLineData) >= 5) &&
                        (
$statLineData[0] == "cpu")
                    )
                    {
                        return array(
                           
$statLineData[1],
                           
$statLineData[2],
                           
$statLineData[3],
                           
$statLineData[4],
                        );
                    }
                }
            }
        }

        return
null;
    }

   
// Returns server load in percent (just number, without percent sign)
   
function getServerLoad()
    {
       
$load = null;

        if (
stristr(PHP_OS, "win"))
        {
           
$cmd = "wmic cpu get loadpercentage /all";
            @
exec($cmd, $output);

            if (
$output)
            {
                foreach (
$output as $line)
                {
                    if (
$line && preg_match("/^[0-9]+\$/", $line))
                    {
                       
$load = $line;
                        break;
                    }
                }
            }
        }
        else
        {
            if (
is_readable("/proc/stat"))
            {
               
// Collect 2 samples - each with 1 second period
                // See: https://de.wikipedia.org/wiki/Load#Der_Load_Average_auf_Unix-Systemen
               
$statData1 = _getServerLoadLinuxData();
               
sleep(1);
               
$statData2 = _getServerLoadLinuxData();

                if
                (
                    (!
is_null($statData1)) &&
                    (!
is_null($statData2))
                )
                {
                   
// Get difference
                   
$statData2[0] -= $statData1[0];
                   
$statData2[1] -= $statData1[1];
                   
$statData2[2] -= $statData1[2];
                   
$statData2[3] -= $statData1[3];

                   
// Sum up the 4 values for User, Nice, System and Idle and calculate
                    // the percentage of idle time (which is part of the 4 values!)
                   
$cpuTime = $statData2[0] + $statData2[1] + $statData2[2] + $statData2[3];

                   
// Invert percentage to get CPU time, not idle time
                   
$load = 100 - ($statData2[3] * 100 / $cpuTime);
                }
            }
        }

        return
$load;
    }

   
//----------------------------

   
$cpuLoad = getServerLoad();
    if (
is_null($cpuLoad)) {
        echo
"CPU load not estimateable (maybe too old Windows or missing rights at Linux or Windows)";
    }
    else {
        echo
$cpuLoad . "%";
    }

?>
up
25
rick at rctonline dot nl
10 years ago
Here is another one that also works on windows. Note that this method is not fast, so be careful in the number of calls to this function.

<?php
function get_server_load() {
   
        if (
stristr(PHP_OS, 'win')) {
       
           
$wmi = new COM("Winmgmts://");
           
$server = $wmi->execquery("SELECT LoadPercentage FROM Win32_Processor");
           
           
$cpu_num = 0;
           
$load_total = 0;
           
            foreach(
$server as $cpu){
               
$cpu_num++;
               
$load_total += $cpu->loadpercentage;
            }
           
           
$load = round($load_total/$cpu_num);
           
        } else {
       
           
$sys_load = sys_getloadavg();
           
$load = $sys_load[0];
       
        }
       
        return (int)
$load;
   
    }
?>
up
7
scott at corelevel dot com
15 years ago
I was having a problem with a large script I need to run - was a loop through about 50,000 records and downloading several pictures for a bunch of them, and updating the database.

the problem came as I started getting visitors to my site, the server would get behind, run out of memory, iowait skyrockets, mysql slows down... was a total downhill spiral.

Use this to fix it.

$load = sys_getloadavg();
$sleep=5;
$maxload=2;
if ($load[0] > $maxload) {
       sleep($sleep);
    echo "Busy server - sleep $sleep seconds<br>";
}

I have to play with the load and the sleep number to find what worked for my script, but now my server does not bog at all.
up
2
kexianbin at diyism dot com
8 years ago
Use this:
<?php
$loads
=sys_getloadavg();
$core_nums=trim(shell_exec("grep -P '^physical id' /proc/cpuinfo|wc -l"));
$load=$loads[0]/$core_nums;
echo
$load;
?>
up
3
tom pittlik
16 years ago
The code below mimics the output of sys_getloadavg(). You may have to tweak the way the substring is captured for different distros.

<?php

function sys_getloadavg_hack()
{
   
$str = substr(strrchr(shell_exec("uptime"),":"),1);
   
$avs = array_map("trim",explode(",",$str));

    return
$avs;
}

print_r(sys_getloadavg_hack());

// Array
// (
//     [0] => 6.24
//     [1] => 4.92
//     [2] => 3.99
// )

?>

This function is a neat way of running low priority or non-essential cron jobs on a busy server - if the load is high, don't continue with the task (and try again in a few minutes time).
up
2
surfchen at gmail dot com
15 years ago
the codes below will provide this function for order versions of PHP.
if (!function_exists('sys_getloadavg')) {
    function sys_getloadavg()
    {
        $loadavg_file = '/proc/loadavg';
        if (file_exists($loadavg_file)) {
            return explode(chr(32),file_get_contents($loadavg_file));
        }
        return array(0,0,0);
    }
}
up
2
Anonymous
12 years ago
To get just current load avg, you can do :

<?php
$output
= shell_exec('cat /proc/loadavg');
$loadavg = substr($output,0,strpos($output," "));
?>
up
2
828586 at gmail dot com
12 years ago
equivalent for windows
<?php
ob_start
();
passthru('typeperf -sc 1 "\processor(_total)\% processor time"',$status);
$content = ob_get_contents();
ob_end_clean();
if (
$status === 0) {
    if (
preg_match("/\,\"([0-9]+\.[0-9]+)\"/",$content,$load)) {
        if (
$load[1] > get_config('busy_error')) {
           
header('HTTP/1.1 503 Too busy, try again later');
            die(
'Server too busy. Please try again later.');
        }
    }
}
?>
up
1
vladvarna at gmail dot com
9 years ago
You can emulate loadavg using this. Can also be used to get iowait

<?php
  
function ProcStats()
   {   
      
$fp=fopen("/proc/stat","r");
       if(
false===$fp)
               return
false;
      
$a=explode(' ',fgets($fp));
      
array_shift($a); //get rid of 'cpu'
      
while(!$a[0])
          
array_shift($a); //get rid of ' '
      
var_dump($a);
      
fclose($fp);
       return
$a;
   }

  
$a=ProcStats();
  
sleep(5);
  
$b=ProcStats();

  
  
$total=array_sum($b)-array_sum($a);
  
  
$loadavg = round(100* (($b[0]+$b[1]+$b[2]) - ($a[0]+$a[1]+$a[2])) / $total, 2); // user+nice+system
  
$iowait= round(100* ($b[4] - $a[4])/$total,2);

?>
up
1
Chris Wheeler
10 months ago
It is important to note that sys_getloadavg() does not return a percentage, and the numbers that it returns are completely meaningless if you do not know the number of CPU cores. To get the number as a percentage you need to divide the value by the number of CPU cores in the system. (eg: if the value is 0.5 and you have two cores, then you are using 25% of the CPU on average). Here is a simple function to get the values as a percent:

<?php
function percentloadavg(){
   
$cpu_count = 1;
    if(
is_file('/proc/cpuinfo')) {
       
$cpuinfo = file_get_contents('/proc/cpuinfo');
       
preg_match_all('/^processor/m', $cpuinfo, $matches);
       
$cpu_count = count($matches[0]);
    }

   
$sys_getloadavg = sys_getloadavg();
   
$sys_getloadavg[0] = $sys_getloadavg[0] / $cpu_count;
   
$sys_getloadavg[1] = $sys_getloadavg[1] / $cpu_count;
   
$sys_getloadavg[2] = $sys_getloadavg[2] / $cpu_count;

    return
$sys_getloadavg;
}
?>
up
-1
Anonymous
8 months ago
simple function to get the cpu load with availability to most os platforms because I haven't actually been able to find a similar protocol if you happen to be testing out various os platforms...

function cpu_load():?string {
    $load='';
    if(strtolower(PHP_OS_FAMILY)=="windows") {
        exec("wmic cpu get loadpercentage /all",$out);
        if($out) {
            foreach($out as $line) {
                if($line&&preg_match("/^[0-9]+\$/",$line)) {
                    $load=$line;
                    break;
                }
            }
        }
    } else {
        $load=sys_getloadavg();
    }
    return $load;
}
up
-1
wowabbs+php at gmail dot com
1 year ago
<?php // Usage processor in Windows using FFI
 
if(!dl("ffi")) // Load the extension
   
throw new Exception('Cound not load the FFI extension.');

  function
GetSystemTimes()
  {
    static
$Kernel32;
   
$Kernel32??=FFI::cdef(<<<'IDL'
      bool GetSystemTimes(long long *IdleTime, long long *KernelTime, long long *UserTime);
      int GetLastError();
    IDL, 'Kernel32.dll');
   
   
$IdleTime   = FFI::new('long long');
   
$KernelTime = FFI::new('long long'); // already has idle time
   
$UserTime   = FFI::new('long long');
 
    if(
$Kernel32->GetSystemTimes(FFI::addr($IdleTime), FFI::addr($KernelTime), FFI::addr($UserTime)))
      return [
       
'Idle'   =>$IdleTime   ->cdata,
       
'Kernel' =>$KernelTime ->cdata, // already has idle time
       
'User'   =>$UserTime   ->cdata,
      ];
    return [];
  }
 
  function
GetSystemTimesDelta()
  {
    static
$Last=null;
    static
$Delta=[0,1];
   
$Times=GetSystemTimes();
   
$Last??=$Times;
   
$Idle =$Times['Idle'   ]-$Last['Idle'   ];
   
$All  =$Times['Kernel' ]-$Last['Kernel' ]+  // Kernel already has idle time
          
$Times['User'   ]-$Last['User'   ];
    if(
$All>1_000_000) // 100ms
   
{
     
$Delta=[$Idle, $All];
     
$Last=$Times;
    }
    return
$Delta;
  }

  function
ProcessorLoad()
  {
    static
$Load=0;
    [
$Idle, $All]=GetSystemTimesDelta();
    if(
$All>0.0)
     
$Load=1-$Idle/$All;
    return
$Load;
  }
 
  function
KbHit()
  {
    Static
$Sys;
   
$Sys??=FFI::cdef('bool _kbhit();', 'msvcrt.dll');
    return
$Sys->_kbhit();
  }
 
  while(!
KbHit())
  {
    echo
str_pad((string)round(ProcessorLoad()*100), 3, ' ', STR_PAD_LEFT), "%\n";
   
sleep(1);
  }
?>

官方地址:https://www.php.net/manual/en/function.sys-getloadavg.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3