后台处理视频上传,什么是精通PHP的方式


Background processing video uploads, what is a proficient way in PHP?

我正在开发一个视频上传网站,我遇到了一个困境:上传的视频需要转换成FLV格式才能显示给访问者,但是,如果我在脚本中执行命令,脚本将悬挂约10-15分钟,而FFMPEG转换视频。

我有一个想法,在数据库中插入一条记录,表明需要处理的文件,然后使用cron作业设置为每5分钟从数据库中选择需要处理的记录,处理它们,然后更新数据库,显示它们已被处理。我担心这是执行太多的进程和服务器崩溃的压力下,所以有没有人有任何解决方案,或一种方法来更好的过程,我的想法?


好的,这就是我现在想到的,所以用户上传视频,并将一行插入到数据库中,表明需要处理视频。cron作业每5分钟检查一组需要处理什么,正在处理,最多说我将五个过程,因此,脚本会检查是否有视频需要处理和多少视频正在处理,如果是小于5,它更新记录表明它正在处理,一旦视频处理,更新记录表明它已处理和cron作业开始,任何想法吗?

Gearman是这类问题的一个很好的解决方案,它允许您立即调度作业,并有任意数量的工人(可能在不同的服务器上)可用来完成它。

一开始你可以在同一台服务器上运行几个worker,但如果你开始遇到负载问题,你可以用更多的worker启动另一台服务器,所以它是水平扩展的。

如果您正在使用PHP-FPM,那么您可以使用PHP.net上记录的fastcgi_finish_request()。FastCGI进程管理器(FPM)

fastcgi_finish_request() -完成请求并刷新所有数据的特殊函数,同时继续做一些耗时的事情(视频转换,统计处理等);

如果你不使用PHP-FPM或者想要更高级的东西,那么你可以考虑使用像Gearman这样的队列管理器,它非常适合你所描述的场景。与使用shell_exec运行进程相比,使用Gearman的优势在于,您可以查看正在运行的作业数量/剩余的作业数量,并检查它们的状态。您还使扩展变得更加容易,因为现在添加作业服务器很简单:

$worker->addServer("10.0.0.1"); 

我喜欢PHP手册中的这个类(参见具体注释):http://www.php.net/manual/en/function.exec.php#88704

基本上,它允许您在*Nix系统上剥离一个后台进程。它返回一个pid,您可以将其存储在会话中。当您重新加载页面以检查它时,只需用保存的pid重新创建ForkedProcess类,就可以检查它的状态。如果已完成,则应执行该过程。

它不允许太多的错误检查,但它非常轻量级。

如果您期望大量流量,您应该认真考虑使用专用服务器。

在单个服务器上,您可以使用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表中,然后每隔5分钟使用cron作业来检测视频何时完成并更新数据库中的相关值。

您可以使用system调用ffmpeg并将输出发送到/dev/null,这将使该调用立即返回,在后台有效地处理它

生成一对工作进程,它们将从消息队列中消费消息,例如beanstalkd。这样你就可以控制并发任务(转换)的数量,也不必为生成进程付出代价(因为进程一直在后台运行)。

我认为它会更快,如果你使用/编码C和使用Redis作为你的消息队列。Redis有一个非常好的c客户端库,名为Hiredis。我不认为这是很难做到的。