За последние 24 часа нас посетили 20824 программиста и 1135 роботов. Сейчас ищет 361 программист ...

Windows 2012. Множественные php.exe - загрузка процессора 100% (в полке)

Тема в разделе "Прочие вопросы по PHP", создана пользователем miketm, 29 ноя 2022.

  1. miketm

    miketm Активный пользователь

    С нами с:
    29 июн 2015
    Сообщения:
    22
    Симпатии:
    0
    Добрый день!

    Подскажите, пожалуйста, может у кого-то будут идеи как решить проблему.
    У меня есть несколько (порядка 10) php скриптов, которые выполняют самые разные задачи: какие-то выполняют арифметические операции, какие-то делают запросы к внешнему веб серверу, какие-то читают/пишут в базу данных mysql, какие-то занимаются обработкой строковых переменных и так далее.

    На Windows Server 2012 у меня взведен WAMP Server (apache, mysql, php). Для каждого скрипта создан bat файл, который вызывает выполнение конкретного скрипта через вызов php.exe.

    Для каждого bat файла в планировщике создано задание, которое выполняется 1 раз в минуту при этом выставлено условие "если задача выполняется еще одну не запускать".

    Все вроде бы замечательно работает. Некоторые скрипты выполняются за пол минуты - другие могут выполняться 30 минут. В любом случае, повторное выполнение скрипта по шедулеру не запускается, пока предыдущее выполнение скрипта не завершилось.

    Все это крутится на машине с 4 ядерным процессором среднего класса (не самый мощный, но и не слабый). Загрузка процессора на машине колеблеться между 5% и 60% (чаще всего 10-20%) в зависимости от того, какие скрипты в конкретный момент выполняются. Это нормально и это меня устраивает. Однако через какое-то количество времени (как правило, через несколько дней), я обнаруживаю, что процессор в полке.

    Открываю диспетчер задач и вижу, что имеется большое количество процессов типа php.exe, при этом большинство из них грузят процессор не более чем на 1%, а вот 2-3 из них грузят проц на 25% (как будто бы каждый из них полностью занимают 1 ядро из 4х).

    Что я делаю: я отключаю выполнение задач в планировщике. Проходит пол часа и ВСЕ мои скрипты гарантированно останавливаются (это видно по логам, которые мои же скрипты и ведут), НО процессы php.exe никуда не пропадают и более того, те самые процессы, которые грузят проц по 25% тоже никуда не пропали и продолжают грузить проц, при этом судя по логам скриптов и задачам в таск менеджере - все скрипты остановлены.

    И только после того как я делаю taskkill php.exe, процессы убиваются и нагрзука спадает.

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

    Будут ли у Вас идеи по поводу того, как понять причины этого явления?


    PS
    В будущем все это хозяйство будет переносится на убунту, но это не самое ближайшее будущее, поэтому пока что хотелось бы разобраться с тем, что есть на винде. Заранее благодарю за любые идеи!
     
  2. alexphp

    alexphp Активный пользователь

    С нами с:
    5 дек 2019
    Сообщения:
    98
    Симпатии:
    12
    Могу предположить, что у вас запускается процесс php.exe каждый раз, когда нужно выполнить скрипт. Когда же скрипт выполняется, он автоматически отключается, а процесс php.exe продолжает висеть в памяти. И так происходит до тех пор, пока эти процессы не перегружают процессор. Попробуйте подтвердить или опровергнуть на практике это предположение. Если оно подтвердится, тогда надо думать, как запускать процесс php.exe один раз, а внутри него каждый раз запускать скрипт, или останавливать процесс вместе со скриптом. Если оно опровергнется, тогда надо делать другие предположения, например, надо будет определить тот момент, когда в процессах появится второй запущенный процесс php.exe, который останется в памяти и далее разбираться уже с этим конкретным процессом.
     
  3. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.816
    Симпатии:
    735
    Адрес:
    Татарстан
    имхо какой-то скрипт лагает уходя в небытие .... типа вечного цикла например
    --- Добавлено ---
    это жесть конечно....
    как вариант:
    вручную запускаешь каждый скрипт и смотришь завершился ли он, и нет ли после него артефактов в процессах
    если есть - выясняешь .. .чеж это скрипт такого делает
     
  4. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    845
    Симпатии:
    130
    такую себе написал когда-то donbidon/lib-process: PHP-process Lock library (github.com)
    суть в том, не даёт работать одному и тому же скрипту отрабатывать, если запущен предыдущий и время модификации лок-файла не протухло.
     
  5. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    PHP:
    1. <?php
    2.  
    3. const CRON_LOCK = 'cron.lock';
    4.  
    5. const CRON_MESSAGE_LOCK = 'message.lock';
    6.  
    7.  
    8.  
    9.  
    10. $exists = file_exists ( CRON_LOCK );
    11.  
    12. $resourse = fopen ( CRON_LOCK, 'w' );
    13.  
    14. if ( ! flock ( $resourse, LOCK_EX | LOCK_NB ) )
    15. {
    16.     exit;
    17. }
    18.  
    19.  
    20.  
    21.  
    22.  
    23.  
    24. if ( $exists )
    25. {
    26.     if ( file_exists ( CRON_MESSAGE_LOCK ) )
    27.     {
    28.         exit;
    29.     }
    30.  
    31.     /* .... */
    32.  
    33.     file_put_contents ( CRON_MESSAGE_LOCK, null );
    34.  
    35.     exit;
    36. }
    37.  
    38. register_shutdown_function ( static function ( string $dir ) use ( $resourse )
    39. {
    40.     flock ( $resourse, LOCK_UN );
    41.  
    42.     if ( is_null ( error_get_last () ) )
    43.     {
    44.         unlink ( $dir . DIRECTORY_SEPARATOR . CRON_LOCK );
    45.     }
    46. }, __DIR__ );
    47.  
    48.  
    49.  
    50.  
    51.  
    52. /* $.... = new ...;
    53.  
    54. ....
    55.  
    56. require '.....'; */
    603602185569304673.png