[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Запуск скрипта в background-e
Страницы: 1, 2
AllesKlar
Ситуация следующая:
Скрипт, запущенный апачем (в браузере) должен запустить еще один скрипт в бекграунде и не ждать от него ответа.

Ну, тоесть нечто типа "/usr/bin/php script.php"
Этот script.php очень ресурсоемкий, бродит по разным серверам, копирует много всякого со всяких репозиториев, создает бекап мастер-базы, идет на другой DB сервер, тянет с собой этот бекап, там все разворачивет, подключает, настраивает и т.д.

В общем, он устанавливет веб-приложение smile.gif
Длится это примерно 5-10 минут, такой роскоши, естественно, апачу не дозволенно, да и не зачем ему.

Крон не подходит, т.к. скрипт запускается один раз в когда-нибудь, и гонять его в холостую смысла нет. Запуск должен быть по команде из вне (Посетитель нажал кнопку "Установить")
Решил сделать на ssh2 и оттуда этот "/usr/bin/php script.php" стартовать. Тем самым решается вопрос timeout, скрип гарантированно отработает и не будет убит апачем.
Но вот, родительский скрипт ждет окончания работы дочернего скрипта.

Как вариант, можно запустить аяксом родительский скрипт, тот запустит по shh дочерний, благополучно умрет через 30 секунд, а у аякса проигнорировать ошибку.
Но, не красиво это как-то...

У кого есть мнения?
Хостеры же как-то разворачивают у себя всякие Друпалы и прочее по команде пользователя из админ-панели.

_____________
[продано копирайтерам]
Winston
Цитата (AllesKlar @ 6.03.2014 - 17:22)
Скрипт, запущенный апачем (в браузере) должен запустить еще один скрипт в бекграунде и не ждать от него ответа

У меня когда то была похожая задача, вот в этой теме http://phpforum.ru/index.php?showtopic=71082&hl= есть код для запуска скрипта в фоне.
AllesKlar
Winston
Спасибо, почитаю вечером.

Нашел такое рещшение (думаю, оно и есть верное)

//Скрипт, который должен работать в бекграунде порождает еще один процес, запуская самого себя. И прекращает работу.
$child_pid = pcntl_fork();
if ($child_pid) {
// Выходим из родительского, привязанного к консоли, процесса
exit();
}
// Делаем основным процессом дочерний.
posix_setsid();


_____________
[продано копирайтерам]
philya
C помощью сокетов в неблокирующем режиме это сделать легко
killer8080
Цитата (AllesKlar @ 6.03.2014 - 17:41)
Нашел такое рещшение (думаю, оно и есть верное)

процесс апача форкать нельзя
перенаправь все потоки в /dev/null и пусти в бекграунд
/usr/bin/php script.php >/dev/null 2>&1 &

если не поможет, юзай nohup
AllesKlar
philya
Никогда не работал с сокетами на php
Собственно, принцип один для всех языков.
Нужен сервер, который будет запущен всегда и слушать порт, пока клиент на него что-либо не отправит.

Это ненужная трата ресурсов, т.к.
Цитата (AllesKlar @ 6.03.2014 - 19:22)
скрипт запускается один раз в когда-нибудь, и гонять его в холостую смысла нет. Запуск должен быть по команде из вне (Посетитель нажал кнопку "Установить")

Но, все равно спасибо


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

Браузер -> Кнопка "Ок" -> Обработчик формы конектится по ssh к серверу и запускает нужный мне скрипт без участия апача, чистым php -> нужный мне скрипт форкает себя и сразу завершается -> обработчик формы дождался завершения запущенного им процесса, сам завершился.
-> -> копия форкнутого процесса работает дальше

_____________
[продано копирайтерам]
killer8080
Цитата (AllesKlar @ 6.03.2014 - 20:44)
Я его запускаю через SSH php CLI и уже этот процес форкаю.

только зачем такой финт ушами? Да ещё и через SSH blink.gif
AllesKlar
killer8080
потому что доступ нужен с повышенными привелегиями.
- запись в каталог, выше, чем DOCUMENT_ROOT
- создание субдомена.
и т.д.

_____________
[продано копирайтерам]
philya
Нет, сокет создается в момент запроса от пользователя, запускает скрипт, и, не дожидаясь ответа, закрывается.
killer8080
Цитата (AllesKlar @ 6.03.2014 - 20:56)
потому что доступ нужен с повышенными привелегиями.

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



Спустя 6 минут, 16 секунд killer8080 написал(а):
владельцем скрипта то же должен быть рут, иначе это дыра
AllesKlar
killer8080
никто не говорит об руте smile.gif
Всю эту кашу варим в тесном контакте с нашими админами, они скорее вены вскроют, нежели дадут рута smile.gif
Просто есть пользователь с конкретными привелегиями для конкретных мест + алиасы команд сервера, выглядищие как hjGFdU , чтов перводе на bash может означать, например mkdir

Бинарник не идет, скрипт на php жесткое условие. я вообще на яве хотел все это писать, но, т.к. яву в нужном объеме знаю я один, мне не дали это делать smile.gif А вдруг увольнять меня, кто потом поддерживать будет? smile.gif

philya
Цитата
Нет, сокет создается в момент запроса от пользователя, запускает скрипт, и, не дожидаясь ответа, закрывается.

Ок, просвети меня тогда.
есть клиент (client.php) и сервер (server.php)
Клиент вообще не знает имя скрипта сервера. Клиент отправляет запрос на адрес + порт
Кто же тогда стартанет server.php ?

_____________
[продано копирайтерам]
killer8080
Цитата (AllesKlar @ 6.03.2014 - 21:16)
Бинарник не идет, скрипт на php жесткое условие

я и не предлагал переписывать всё на C. Бинарник только для старта скрипта под нужным suid-ом, и не нужно устанавливать не нужное безопасное соединение сервера самим с собой.
zelenuy
AllesKlar
Делаешь сокет, по команде включаешь и выключаешь из вне, сам раньше такими вещами баловался)
philya
В данном случае сокет его(нужный скрипт) и стартанет и закроется по желанию.
Вот простой пример:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
@socket_connect($socket, "ip-адрес сервера", 80);

$buf = "GET /имя исполняемого файла.php HTTP/1.1\r\n"
. "Host: имя сервера, типа mysite.ru\r\n"
. "Connection: close\r\n"
. "\r\n";

socket_set_nonblock($socket);
socket_write($socket, $buf);
socket_close($socket);
killer8080
philya
и что это даёт? Тяжелый скрипт все равно будет занимать воркер апача.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.