Добрый день! Подскажите, пожалуйста, может у кого-то будут идеи как решить проблему. У меня есть несколько (порядка 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 В будущем все это хозяйство будет переносится на убунту, но это не самое ближайшее будущее, поэтому пока что хотелось бы разобраться с тем, что есть на винде. Заранее благодарю за любые идеи!
Могу предположить, что у вас запускается процесс php.exe каждый раз, когда нужно выполнить скрипт. Когда же скрипт выполняется, он автоматически отключается, а процесс php.exe продолжает висеть в памяти. И так происходит до тех пор, пока эти процессы не перегружают процессор. Попробуйте подтвердить или опровергнуть на практике это предположение. Если оно подтвердится, тогда надо думать, как запускать процесс php.exe один раз, а внутри него каждый раз запускать скрипт, или останавливать процесс вместе со скриптом. Если оно опровергнется, тогда надо делать другие предположения, например, надо будет определить тот момент, когда в процессах появится второй запущенный процесс php.exe, который останется в памяти и далее разбираться уже с этим конкретным процессом.
имхо какой-то скрипт лагает уходя в небытие .... типа вечного цикла например --- Добавлено --- это жесть конечно.... как вариант: вручную запускаешь каждый скрипт и смотришь завершился ли он, и нет ли после него артефактов в процессах если есть - выясняешь .. .чеж это скрипт такого делает
такую себе написал когда-то donbidon/lib-process: PHP-process Lock library (github.com) суть в том, не даёт работать одному и тому же скрипту отрабатывать, если запущен предыдущий и время модификации лок-файла не протухло.
PHP: <?php const CRON_LOCK = 'cron.lock'; const CRON_MESSAGE_LOCK = 'message.lock'; $exists = file_exists ( CRON_LOCK ); $resourse = fopen ( CRON_LOCK, 'w' ); if ( ! flock ( $resourse, LOCK_EX | LOCK_NB ) ) { exit; } if ( $exists ) { if ( file_exists ( CRON_MESSAGE_LOCK ) ) { exit; } /* .... */ file_put_contents ( CRON_MESSAGE_LOCK, null ); exit; } register_shutdown_function ( static function ( string $dir ) use ( $resourse ) { flock ( $resourse, LOCK_UN ); if ( is_null ( error_get_last () ) ) { unlink ( $dir . DIRECTORY_SEPARATOR . CRON_LOCK ); } }, __DIR__ ); /* $.... = new ...; .... require '.....'; */