Как управлять загрузкой процессора на php?

318
24 февраля 2017, 03:19

Наверняка вы сталкивались с задачей когда писали парсеры больших файлов или когда писали высоконагруженные скрипты - сталкивались с тем что процессор нагружен на 100% и если это происходит на сервере, то другие пользователи не могут получить доступ к ресурсам - с этой проблемой столкнулся и я. только через год после возникновения проблемы удалось на мой взгляд найти удовлетворительное решение.

Задача заключается собственно вот в чем: нагрузка на процессор не должна превышать n % (n вы задаете сами). Актуально это только для высоконагруженных процессов имеется ввиду то, что сервак у вас выступает в качестве вычислительной машины.

Если же вы знаете способы не нагружать процессор на 100% настройками сервера - выложите сюда ответы. Если будет необходимо отредактировать вопрос или ответ - я это сделаю - только укажите что редактировать в комментарии.

Answer 1

Ответом на этот вопрос послужила статья о том как замерять нагруженность процессора, исходя из приведенных функций - вот как удалось решить проблему контроля нагрузки на процессор

function onRequestStart() {
        $dat = getrusage();
        define('PHP_TUSAGE', microtime(true));
        define('PHP_RUSAGE', $dat["ru_utime.tv_sec"]*1e6+$dat["ru_utime.tv_usec"]);
    }
    function getCpuUsage() {
        $dat = getrusage();
        $dat["ru_utime.tv_usec"] = ($dat["ru_utime.tv_sec"]*1e6 + $dat["ru_utime.tv_usec"]) - PHP_RUSAGE;
        $time = (microtime(true) - PHP_TUSAGE) * 1000000;
        // cpu per request
        if($time > 0) {
            $cpu = sprintf("%01.2f", ($dat["ru_utime.tv_usec"] / $time) * 100);
        } else {
            $cpu = '0.00';
        }
        return $cpu;
    }
    $start=time();
    onRequestStart();//запускается в начале скрипта
    $a=1000000;
    $size=10000000;
    $counter=0;
    $timeout=100000;
    for($i=0;$i<=$size;$i++){
        $a+=100;
        if(getCpuUsage()>80){//если загрузка процессора достигла 80% погружаем процесс на одну сотую секунды в сон
            usleep($timeout);
            ++$counter;
        }
    }
    $end=time()-$start;
    echo 'Спал '.$timeout*$counter/1000000 .' секунд; ушло времени '.$end.' c';
    gc_disable(); //чистка мусора из памяти сервера

вот результаты теста

$timeout=1000000; //Спал 8 секунд; ушло времени 48 c - результатов не дало - процессор загружался на 100%
$timeout=100000; //Спал 7.5 секунд; ушло времени 46 c
$timeout=10000; //Спал 7.95 секунд; ушло времени 48 c
$timeout=1000;  //Спал 7.888 секунд; ушло времени 49 c
$timeout=100;   //Спал 5.3308 секунд; ушло времени 50 c
$timeout=10;    //Спал 1.18124 секунд; ушло времени 47 c
$timeout=1;     //Спал 0.152863 секунд; ушло времени 50 c

во всех случаях, кроме первого, нагрузка на процессор не превышала 85% по результатам htop - возможно это связано с тем, что htop обновляется раз в секунду

также я заметил что с уменьшением времени для сна - увеличивается количество засыпаний с 3500 до 250 000 при том что всего циклов 10 000 000

READ ALSO
Как спарсить кинопоиск [требует правки]

Как спарсить кинопоиск [требует правки]

Добрый день! Хочу сделать сайт на подобии имхонетаДля этого мне нужно собрать БД со всеми фильмами и постоянно их обновлять

412
Определение мобильной темы в Wordpress

Определение мобильной темы в Wordpress

Есть плагин WP Mobile Detect, через него можно вставлять шорткоды, а также их можно вставлять в тему: wpmd_is_notphone(), wpmd_is_phone() и другие

301
Парсер для facebook. Какую схему выбрать

Парсер для facebook. Какую схему выбрать

Есть задача, нужен парсер постов facebook по фильтру на phpЕсть два предпологаемых варианта решения задачи:

325
Снова вопрос по Smarty

Снова вопрос по Smarty

Имеется такой вот цикл:

264