PHP-скрипт «перезапускается», создавая новые экземпляры самого себя - PullRequest
0 голосов
/ 16 декабря 2018

Я разработал сайт с использованием Zend Framework 2. По сути, это сайт сравнения цен, который интегрируется со многими из ведущих партнерских сетей.Я написал скрипт, который проверяет цены в каждой партнерской сети, а затем обновляет мою локальную базу данных с этой ценой.В зависимости от того, с какой партнерской сетью я связываюсь, возможно, я звоню по API (Amazon или CJ.com) или просматриваю канал XML-продукта (Pepperjam или LinkShare).Фид продуктов XML будет размещаться локально.

В настоящее время существует около 3500 пометок, которые я проверяю с помощью этого сценария.Подавляющее большинство из них (95% и более) ориентированы на канал XML-продуктов.Я бы оценил, что этот сценарий, вероятно, займет около 10 минут.Некоторые из рассматриваемых XML-файлов имеют размер около 8 МБ.

Я тщательно протестировал этот сценарий в своей локальной среде и приложил немало усилий, чтобы убедиться в отсутствии утечки памяти или чего-либо подобногочто может вызвать проблемы с производительностью.В качестве примера я по возможности использовал потоки данных, чтобы избежать многократного помещения XML-файла в память и т. Д. Достаточно сказать, что сценарий выполняется локально без проблем.

Этот сценарий предназначен длязапускать как задание cron, однако у меня есть способ запустить его через специальный административный интерфейс администратора.Локально, именно так я запускаю сценарий для запуска, и все идет довольно гладко.

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

Проблема # 1 : Если я запускаю сценарий ad-hoc через HTTP-запрос, я нахожу, что он будет работать в течение пары минут, а затем сценарий запустится снова (так что теперь, очевидно, запущены два экземпляра).Подождите еще пару минут, и начнется третье, и т. Д. ..... Вот пример, когда я запустил скрипт в 22:09 с помощью HTTP-запроса.

Снимок экрана процессаmanager

Само собой разумеется, я НЕ запускаю его через HTTP-запрос, потому что это только доставляет мне неприятности с моим провайдером веб-хостинга:)

Problem #2 : Когда скрипт запускается на сервере, запущенном через задание cron, он не может быть завершен.Я взял рабочую копию базы данных и взял ее локально вместе с файлами XML, она работает нормально.Так что это не должно быть проблемой с плохими данными, выставляющими плохой код.Мое наблюдение таково - сценарий почти запускается в течение того же периода времени - до прерывания, или прекращения, или чего-то еще.Последняя обновленная запись, как правило, помечается меткой времени примерно через 4 минуты 30 секунд (если память служит) после запуска сценария.Список SKU постоянно меняется, поэтому запись, в которой он заканчивается, отличается, но время последнего обновления почти одинаково каждый раз.Ничего не регистрируется в журналах ошибок.Я контролировал ресурсы сервера через команду SSH top, и в этом нет ничего необычного.Использование ЦП контролируется, а используемая память не увеличивается.

У меня есть учетная запись общего хостинга через Bluehost.Я думал, что, возможно, это была проблема с максимальным временем выполнения скрипта.Я продлил максимальное время выполнения в самом скрипте и через php.ini.Ничего не изменилось.

Так что я думаю, что я ищу некоторые свежие идеи о том, куда идти дальше.Какие вопросы мне следует задавать моей хостинговой компании, чтобы они могли помочь мне разобраться в этом.Они только несколько полезны, если не сказать больше.Может ли быть какое-то ограничение на мою учетную запись хостинга?Запуск какого-то автоматического монитора, который убивает сценарий?Какие типы настроек Apache могут быть проблематичными для скриптов такого типа?Настройки PHP.ini?Абсолютно любой вклад, который вы можете предоставить, будет полезен.

И почему при срабатывании через HTTP он будет продолжать раскручивать новые экземпляры?Я думаю, я мог бы жить без запуска вручную и запускать его только через задание cron, но это тоже не работает.Так что .... интересно услышать мнение сообщества по этому поводу.Спасибо!

1 Ответ

0 голосов
/ 16 декабря 2018

Я не видел ваш сценарий, и я не работал с вашим хостером, поэтому все ниже - просто предположение - и предложение.

Учитывая ваше описание, я бы сказал, что вы правы, что вашскрипт мог быть убит тайм-аутом при запуске из cron.Я не уверен, почему он продолжает порождать новые экземпляры вашего скрипта, когда вы выполняете его вручную через HTTP-запрос, но это также может быть связано с таймаутом (например, если у них есть логика, которая перезапускает скрипт, если он не произвелвывод в течение определенного времени или что-то в этом роде.

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

Позвольте мне предложить вам вариант на случай, если ваш провайдер не сможет помочь.

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

Как насчет того, чтобы создать временную таблицу (или файл?- просто любое постоянное хранилище на сервере), которое сохранит идентификатор последней обработанной записи сценария или NULLесли сценарий успешно завершен.Таким образом, вы сможете запустить свой сценарий с последней обработанной записи (если последняя обработанная запись имела id = 1000, добавьте ... WHERE id > 1000 к основному запросу, который выбирает SKU), и вам будет все равно, еслиСценарий завершил свою первую попытку или нет (если нет, он продолжит обработку с того самого момента, когда он был убит, со второй попытки).

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

Основная идея такова: если сценарию не удается обработать все SKU одновременно,просто перезапустите его, чтобы он не потерял свой прогресс.

...