sys_getloadavg

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

sys_getloadavg获取系统负载平均值

描述

sys_getloadavg(): 数组|false

返回三个样本,分别代表过去 1、5 和 15 分钟的系统负载平均值(系统运行队列中的进程数)。如果失败,则返回 false

参数

此函数没有参数。

返回值

返回一个包含三个样本(过去 1、5 和 15 分钟)的 数组

示例

示例 #1 sys_getloadavg() 示例

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

注释

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

添加注释

用户贡献的注释 12 则注释

stanislav dot eckert at vizson dot de
8 年前
用于在 Windows 和 Linux 下获取当前 CPU 负载百分比值的函数。

注意:函数是 getServerLoad()。它将返回当前 CPU 负载百分比的小数,如果出现问题(例如,访问权限不足),则返回 NULL。

<?php

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

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

if (
$stats !== false)
{
// 移除双空格以使使用 explode() 提取值更容易
$stats = preg_replace("/[[:blank:]]+/", " ", $stats);

// 分隔行
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
$stats = explode("\n", $stats);

// 分隔值并查找主 CPU 负载行
foreach ($stats as $statLine)
{
$statLineData = explode(" ", trim($statLine));

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

return
null;
}

// 返回服务器负载百分比(仅数字,无百分号)
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"))
{
// 收集 2 个样本 - 每个样本的周期为 1 秒
// 参见: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))
)
{
// 获取差值
$statData2[0] -= $statData1[0];
$statData2[1] -= $statData1[1];
$statData2[2] -= $statData1[2];
$statData2[3] -= $statData1[3];

// 将用户、nice、系统和空闲的 4 个值加起来,并计算空闲时间的百分比(这是 4 个值的一部分!)
$cpuTime = $statData2[0] + $statData2[1] + $statData2[2] + $statData2[3];

// 反转百分比以获得 CPU 时间,而不是空闲时间
$load = 100 - ($statData2[3] * 100 / $cpuTime);
}
}
}

return
$load;
}

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

$cpuLoad = getServerLoad();
if (
is_null($cpuLoad)) {
echo
"CPU 负载无法估计(可能是 Windows 太旧,或者 Linux 或 Windows 上缺少权限)";
}
else {
echo
$cpuLoad . "%";
}

?>
rick at rctonline dot nl
12 年前
这里还有一个可以在 Windows 上运行的代码。请注意,此方法并不快,因此请小心调用此函数的次数。

<?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;

}
?>
Chris Wheeler
3 年前
重要的是要注意,sys_getloadavg() 不返回百分比,如果您不知道 CPU 内核的数量,它返回的数字毫无意义。要将值作为百分比获取,您需要将该值除以系统中的 CPU 内核数。(例如:如果值为 0.5 并且您有两个内核,那么您平均使用 25% 的 CPU)。这是一个简单函数,可以将值作为百分比获取

<?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;
}
?>
scott at corelevel dot com
17 年前
我在运行一个大型脚本时遇到了问题——它需要遍历大约 50,000 条记录,并为其中的一部分下载几张图片,然后更新数据库。

问题在于,当我开始有访问者访问我的网站时,服务器会落后,内存不足,iowait 急剧上升,mysql 速度变慢……这完全是一条下坡路。

使用此代码来解决问题。

$load = sys_getloadavg();
$sleep=5;
$maxload=2;
if ($load[0] > $maxload) {
sleep($sleep);
echo "服务器繁忙 - 休眠 $sleep 秒<br>";
}

我必须调整负载和休眠时间,才能找到适合我的脚本的设置,但现在我的服务器完全没有卡顿。
Anonymous
14 年前
要只获取当前负载平均值,您可以执行以下操作

<?php
$output
= shell_exec('cat /proc/loadavg');
$loadavg = substr($output,0,strpos($output," "));
?>
tom pittlik
18 年前
以下代码模拟 sys_getloadavg() 的输出。您可能需要调整子字符串的获取方式,以适应不同的发行版。

<?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
// )

?>

此函数是在繁忙服务器上运行低优先级或非必要 cron 作业的一种巧妙方法——如果负载很高,请不要继续执行任务(并在几分钟后重试)。
kexianbin at diyism dot com
10 年前
使用此代码
<?php
$loads
=sys_getloadavg();
$core_nums=trim(shell_exec("grep -P '^physical id' /proc/cpuinfo|wc -l"));
$load=$loads[0]/$core_nums;
echo
$load;
?>
surfchen at gmail dot com
18 年前
以下代码将为旧版本的 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);
}
}
828586 at gmail dot com
14 年前
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(
'服务器太忙。请稍后再试。');
}
}
}
?>
Anonymous
2 年前
一个简单的函数,用于获取 CPU 负载,并且对大多数操作系统平台可用,因为实际上我还没有找到类似的协议,如果您碰巧正在测试各种操作系统平台……

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;
}
wowabbs+php at gmail dot com
3 年前
<?php // 在 Windows 上使用 FFI 的使用处理器
if(!dl("ffi")) // 加载扩展
throw new Exception('无法加载 FFI 扩展。');

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'); // 已经包含空闲时间
$UserTime = FFI::new('long long');

if(
$Kernel32->GetSystemTimes(FFI::addr($IdleTime), FFI::addr($KernelTime), FFI::addr($UserTime)))
return [
'Idle' =>$IdleTime ->cdata,
'Kernel' =>$KernelTime ->cdata, // 已经包含空闲时间
'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' ]+ // 内核已经包含空闲时间
$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);
}
?>
vladvarna at gmail dot com
12 年前
您可以使用此方法模拟 loadavg。也可以用来获取 iowait

<?php
function ProcStats()
{
$fp=fopen("/proc/stat","r");
if(
false===$fp)
return
false;
$a=explode(' ',fgets($fp));
array_shift($a); // 去除 'cpu'
while(!$a[0])
array_shift($a); // 去除 ' '
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);

?>
To Top