Фоновая обработка загрузки видео, какой опытный способ в PHP? - PullRequest
4 голосов
/ 14 августа 2011

Я занимаюсь разработкой сайта для загрузки видео и столкнулся с дилеммой: загруженные видео необходимо преобразовать в формат FLV, чтобы они отображались посетителю, но если я выполню команду в сценарии, сценарий зависать в течение 10-15 минут, пока FFMPEG конвертирует видео.

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


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

Ответы [ 6 ]

3 голосов
/ 14 августа 2011

Если вы используете PHP-FPM, вы можете использовать fastcgi_finish_request () , как описано в PHP.net. FastCGI Process Manager (FPM)

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

Если вы не используете PHP-FPM или хотите что-то более продвинутое, то вы можете использовать менеджер очередей, такой как Gearman , который идеально подходитподходит для сценария, который вы описываете.Преимущество использования Gearman перед запуском процесса с shell_exec заключается в том, что вы можете посмотреть, сколько запущено заданий / сколько осталось, и проверить их статусы.Вы также значительно упрощаете масштабирование, поскольку добавление серверов заданий теперь тривиально:

$worker->addServer("10.0.0.1"); 
3 голосов
/ 14 августа 2011

Gearman является хорошим решением для такого рода проблем, оно позволяет вам мгновенно отправить задание и иметь любое количество рабочих (которые могут быть на разных серверах) для его выполнения.

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

1 голос
/ 14 августа 2011

Мне нравится этот класс (см. Конкретный комментарий) в руководстве по PHP: http://www.php.net/manual/en/function.exec.php#88704

По сути, он позволяет вам запускать фоновый процесс в * системах Nix.он возвращает pid, который вы можете сохранить в сеансе.Когда вы перезагрузите страницу, чтобы проверить ее, вы просто воссоздаете класс ForkedProcess с сохраненным pid, и вы можете проверить его статус.Если он завершен, процесс должен быть завершен.

Он не позволяет много проверять ошибки, но невероятно легкий.

0 голосов
/ 14 августа 2011

Создает пару рабочих процессов, которые будут получать сообщения из очереди сообщений, например, beanstalkd .Таким образом, вы можете контролировать количество одновременных задач (конверсий), а также не должны платить цену порождающих процессов (потому что процессы продолжают работать в фоновом режиме).

Я думаю, что было бы намного быстрее, если бывы использовали / закодировали C и использовали Redis в качестве очереди сообщений.Redis имеет очень хорошую клиентскую библиотеку c с именем Hiredis .Я не думаю, что это было бы безумно сложно сделать.

0 голосов
/ 14 августа 2011

Если вы ожидаете много трафика, вы должны серьезно рассмотреть выделенный сервер.

На одном сервере вы можете использовать shell_exec вместе с командой UNIX nohup, чтобы получить PID процесса.

   function run_in_background($Command, $Priority = 0)
   {
       if($Priority)
           $PID = shell_exec("nohup nice -n $Priority $Command 2> /dev/null & echo $!");
       else
           $PID = shell_exec("nohup $Command 2> /dev/null & echo $!");
       return($PID);
   }
   function is_process_running($PID)
   {
       exec("ps $PID", $ProcessState);
       return(count($ProcessState) >= 2);
   }

Полное описание этого метода приведено здесь: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

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

0 голосов
/ 14 августа 2011

Вы можете вызвать ffmpeg, используя system и отправить вывод на /dev/null, это сразу же вернет этот вызов, эффективно обработав его в фоновом режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...