Функция PHP sys_getloadavg()
возвращает массив с тремя значениями, показывающими среднее число процессов в очереди выполнения системы за последние 1, 5 и 15 минут соответственно.
Как перевести эту продукцию в проценты?
Проценты являются относительными единицами измерения. Это означает, что мы должны знать диапазон или минимальные и максимальные значения измеряемой величины. функция sys_getloadavg()
оценивает производительность всей системы, не отдельный уровень загрузки процессора, или использование памяти, файловой системы или базы данных. Он возвращает числа с плавающей запятой, показывающие, сколько процессов находилось в очереди выполнения за последний интервал времени.
Я провел некоторый эксперимент с моим MacBook Pro (8 процессорных ядер) и PHP 7.0, чтобы выяснить диапазон значений, создаваемых sys_getloadavg()
, У меня средние цифры от 1,3 до 3,2. Когда я параллельно запускаю программу конвертации видео, максимальный результат подскочил до 18,9. Кстати, во всех случаях я не зафиксировал существенных потерь в скорости загрузки веб-страниц. Это означает, что вся система не была перегружена.
Давайте возьмем 100% загрузки системы, когда веб-страница не загружается в течение разумного времени, скажем, 10 секунд. Я не знаю, какие значения вернутся sys_getloadavg()
в этом случае, но я думаю, что это будет что-то большое.
Мое решение очень простое. Давайте измерим средний уровень нагрузки системы и будем постоянно сохранять результаты как минимальные и максимальные значения. Когда система работает быстрее или медленнее, мы будем обновлять min и max новыми значениями. Итак, наша программа будет ‘учить’ система и становится все более и более точной. Значение последней минуты будет сравниваться с сохраненным диапазоном и конвертироваться в проценты как (loadavg - min)/((max - min) / 100)
:
$performance = sys_getloadavg();
try {
$rangeFile = 'sys_load_level.txt';
$range = file($rangeFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$performance = array_merge($performance, $range);
$min = min($performance);
$max = max($performance);
if ($range[0] > $min || $range[1] < $max)
file_put_contents($rangeFile, [$min.PHP_EOL, $max.PHP_EOL]);
}
catch (Exception $e) {
$min = min($performance);
$max = max($performance);
file_put_contents($rangeFile, [$min.PHP_EOL, $max.PHP_EOL]);
}
$level = intval(($performance[0] - $min) / (($max - $min) / 100.0));
Других решений пока нет …