http status code 504 — Как запустить скрипт php в оболочке на моем сайте?

У меня есть скрипт PHP, расположенный на /var/www/site/update.php full, Скрипт запускается автоматически из cron:

/usr/bin/php /var/www/site/update.php full

Но когда я запускаю тот же скрипт с моего сайта:

<?php exec("/usr/bin/php /var/www/site/update.php full") ?>

Он работает около 20 минут, а затем начинает отображать множество сообщений об ошибках. При этом страница перестает загружаться и пишет error 504 Gateway Time-out на экран.

Я думаю, что curl тоже не поможет. Есть ли другие варианты?
вопрос в том, как запустить, чтобы он мог работать независимо от браузера. код уже существует и разработан. теперь он проходит через крон каждый час. но необходимо запустить его незапланированно, нажав кнопку или ссылку на сайте.

1

Решение

Вы можете изменить set_time_limit(-1); в сценарии PHP, чтобы предотвратить смерть PHP, но 504 звучит так, как будто у вас запущен nginx, поэтому вам также придется изменить его временные ограничения для этого конкретного ресурса, используя location узел конфигурации (или основной конфиг ngix) для установки параметров * _timeout

если вам не нужно обновлять вывод каждую секунду, я бы сделал это:

  1. когда кнопка нажата, сохранить флаг «нажата» в каком-то файле

    если ($ _ POST [ ‘schedule_script_button’]) {
    потрогать (DIR.»/Script_is_scheduled.flag»);
    }

  2. используйте cron для запуска скрипта каждую минуту

* * * * * php /var/www/example.com/my-long-script.php

  1. сценарий должен проверить, установлен ли этот флаг, в противном случае прекратить

    если (! file_exists (DIR.»/Script_is_scheduled.flag»)) {
    выход;
    }
    // здесь выполняется полная логика скрипта

  2. если флаг установлен, запустите сценарий и сохраните вывод в файл. если вы используете crontab, вы можете использовать echo в скрипте, и crontab следует изменить следующим образом:

* * * * * php /var/www/example.com/my-long-script.php > /var/www/example.com/my-script-output.txt

  1. разрешить веб-интерфейсу читать «выходной файл» с другого URL. Т.е. теперь вы можете прочитать my-script-output.txt используя file_get_contents Функция PHP и просто эхо его содержимого.

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

0

Другие решения

То, чего вы пытаетесь достичь, не может быть реализовано в парадигме PHP Web: ваш скрипт выполняется в контексте HTTP-запроса; его выполнение всегда будет прекращено в тот момент, когда ваш посетитель прерывает запрос (закрывает вкладку или браузер, выключает WiFi и т. д.).

Чтобы запустить выполнение длинной фоновой задачи из HTTP-запроса (либо щелчок кнопки, либо программный вызов curl), ваш сервер должен состоять из нескольких компонентов: обычно это очередь сообщений (например, RabbitMQ).

Нажатие кнопки вызовет только сообщение «Задание»: поместите (строковое) сообщение в очередь сообщений, которое описывает тип запуска и параметры (например, сериализованным способом PHP или JSON), а затем сразу же возвращается , Ваш посетитель получает быстрый HTTP-ответ, который гласит: «Ваша работа успешно поставлена ​​в очередь».

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

С состоянием длинной работы ваш посетитель может ознакомиться на специальной странице своих текущих работ, где он также может получить результат для загрузки или просмотра и т. Д. (Пример: различные службы «Преобразование YouTube в Mp3» по всему Интернету)

Это единственный надежный способ обработки длинных фоновых задач, запускаемых онлайн.

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

Вы можете найти в RabbitMQ How-To a подробное руководство по PHP.

0

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

0
По вопросам рекламы [email protected]