2011-08-14 7 views
4

私は、ビデオのアップロードサイトを開発していると私はジレンマに走っています:ビデオは、訪問者に表示されるために、FLV形式に変換する必要がアップロードされますが、私はスクリプト内のコマンドを実行すると、スクリプトがハングしますFFMPEGがビデオを変換している間、約10〜15分間。バックグラウンド処理の動画アップロード、PHPの熟練した方法は何ですか?

私は、ファイルを処理する必要があることを示すレコードをデータベースに挿入し、5分ごとに設定されたcronジョブを使用して、処理が必要なデータベースからレコードを選択し、処理してからそれらが処理されたことを示すデータベースを更新します。私の心配は、あまりにも多くのプロセスを実行し、サーバーが緊張の下でクラッシュするので、誰にもこれに対する解決策、または私が念頭に置いているプロセスをより良くする方法がありますか?


さて、これは今私は考えているものであり、ユーザがビデオをアップロードし、行がビデオを示すデータベースに挿入され、処理される必要があります。 5分ごとに設定されたcronジョブは、処理する必要があるものと処理されているものを確認します。一度に最大5つのプロセスを作成するので、スクリプトは処理する必要があるビデオと、処理されていれば、それが処理されていることを示すレコードを更新し、ビデオが処理されたら、それが処理されたことを示すレコードを更新し、cronジョブが再び開始される。

答えて

0

あなたは多くのトラフィックを期待していた場合、あなたが真剣に専用のサーバーを検討すべきです。

単一のサーバーでは、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/

あなたはおそらくMySQLのテーブルにPIDのリストを配置し、ビデオが完了したときに検出するために、5分ごとにあなたのcronジョブを使用することができますし、データベース内の関連する値を更新します。

0

ffmpegを使用してsystemを送信し、出力を/dev/nullに送信すると、すぐにコールが戻って効果的にバックグラウンドで処理されます。

+0

私はそれを考えましたが、私は心配していました。 1.同時に多くの人がビデオをアップロードしようとしている場合、効果的な方法がないので、サーバは負荷をかけてクラッシュする可能性があります。生成されたプロセスの量を制御します。 2.ファイルが変換されたら、どのようにユーザーに報告することができますか?私はプロセスIDを取得し、このプロセスが終了した場合、cronジョブのチェックを持っていると仮定し、データベースを更新しますか? – Muggles

+0

負荷がかかっても失敗しますか? – Alfred

1

私は、PHPマニュアルで(特定のコメントを参照してください)このクラスを愛して:http://www.php.net/manual/en/function.exec.php#88704

は基本的に、それはあなたが* nixシステム上のバックグラウンド・プロセスをスピンオフすることができます。セッションに格納できるpidを返します。ページを読み込んで確認するときは、pidという名前のForkedProcessクラスを再作成するだけで、その状態を確認できます。完了したら、プロセスを完了する必要があります。

それは多くのエラーチェックのために許可されていませんが、それは非常に軽量です。

+0

これは関数であり、クラスではありません。 –

+0

私がリンクした具体的なコメントは、Processクラスのコメントでした。申し訳ありませんが明確でない場合。 – OverZealous

+0

私の悪い、ページは最初に周りのコメントにスクロールしませんでした。 –

3

Gearmanは、この種の問題を解決するのに適しています。ジョブを即時に送信したり、別のサーバーにある可能性があるワーカーを任意の数だけ使用して実行できます。あなたと一緒に起動するには

は、同じサーバー上のいくつかの労働者を実行することができますが、負荷の問題に実行するために開始するならば、あなただけのいくつかのより多くの労働者を別のサーバを起動することができますので、それは水平にスケーラブルです。

+0

これは、私が今気にしていたことのためにはあまり進んでいないようですが、サーバーへのトラフィックがかなり多い場合は、将来的に使用する予定です。 – Muggles

3

あなたは、あなたがPHP.netに記載されているようfastcgi_finish_request()を利用することができますPHP-FPMを使用している場合。 FastCGI Process Manager (FPM)

fastcgi_finish_request() - 特殊機能要求を終了し、何か時間のかかる(動画変換などの処理統計)を行うために継続しながら、すべてのデータをフラッシュします。

あなたはPHP-FPMを使用したり、より高度な何かをしたくないしている場合、あなたはあなたが記述しているシナリオに最適ですGearmanのような、キュー・マネージャを使用して検討するかもしれません。 shell_execでプロセスを実行するよりもGearmanを使う利点は、実行中のジョブの数/残っているジョブの数と状態を確認できることです。

$worker->addServer("10.0.0.1"); 
0

beanstalkdのためのようなメッセージキューからメッセージを消費しますワーカープロセスのスポーンカップル:あなたはまた、ジョブサーバを追加することになりました些細だとはるかに簡単にスケーリングします。このようにして、並行タスク(コンバージョン)の数を制御したり、プロセスがバックグラウンドで実行され続けるため、産出プロセスの価格を支払う必要がありません。

私はあなたが/ Cを使用してメッセージキューとしてRedisを使用した場合、さらに高速になると思います。 Redisには、非常に良いCクライアントライブラリ​​があります。私はこれが達成するために非常に難しいとは思わない。

関連する問題