2008-09-01 33 views
8

PHPスクリプトをデーモンとして実行する最良の方法は何ですか?また、再起動が必要かどうかを確認する最良の方法は何ですか。PHPスクリプトをデーモンとして実行する最良の方法は何ですか?

私は24/7を実行する必要があるいくつかのスクリプトを持っており、ほとんどの部分は私がnohupを使用してそれらを実行することができます。しかし、それらがダウンした場合、それを自動的に再起動できるように監視する最善の方法は何ですか?

+0

最高の唯一の方法はプロセスの監督です。それは、親プロセスが子供をフォークし、その出口信号を捕らえることを中心にしています。終了信号が正常でない場合は、子プロセスを再起動します。子供が死亡した場合、親(監督者)はそれを再開する。この質問に対して提供されたすべての回答は、最高で悪いです。 –

答えて

4

あなたは(それはあなたが好きな言語で書くことができます)スクリプトを実行するcronを使用、(あなたが共有など、ホスティングにしている)これを実行するごとに数を(適切な)のinit構造を使用できない場合実行中かどうかを確認し、必要に応じて再起動します。

+0

「これを行うための(適切な)init構造の使用」とは何ですか?また、これがスクリプトの実行を保証する問題をどのように解決するのでしょうか? –

-1

TBH、PHPは、おそらくそれがために設計されたものを、本当に、このための最良のツールではないではありません。私はあなたがこれを試みるときに起こったメモリリークや他の悪い事について聞いたことがあります。また、PHPには、スクリプトの実行ごとに限られた量のリソースID(ファイルハンドル、db接続など)があります。私はアプリのこれらの種類を書いて任意の実際の経験を持っていないが、私はPHPは、あなたがやろうと何のために右ではありません知っていますけれども

は、PythonやPerlの多分、何か他のものを使用する方が良いです。

+0

失礼を犯さずに、この回答を削除してください。巨大な誤報と知識不足があります。 「有限量のリソースID」は、PHPではなく、オペレーティングシステムによって処理されます。したがって、他の言語でも全く同じ制限があります。 PHPがC言語のプロセス制御に同じライブラリを使用しているのを見て、C言語とまったく同じパワーを持っているのを見て、なぜそれが適切なツールではないかを詳しく説明することができます。しかし、私は意図的な誤報の広がりを理解することはできません.. –

1

私は、wgetコマンドを実行し、共有サーバー上の/ dev/nullに結果を送信して成功を収めてきました。

3

あなたのデーモンを再起動するために迅速かつ汚れのcron:

* * * * * USER ps auxww | grep SCRIPTNAME > /dev/null || SCRIPTNAME 

デーモンは、スクリプトの名前と同じように動作し、SCRIPTNAMEユーザーとUSERを交換してください。これを/etc/cron.d/restart_php_daemonに貼り付けてください。毎分実行する必要があります。最初の**/2または*/5に変更する頻度を減らしてください。

UPDATE

あなた自身のcrontabにこれを入れている場合:

実行crontab -eおよび追加:

* * * * * ps auxwww | grep SCRIPTNAME > /dev/null || SCRIPTNAME 
+0

これは本当に便利なイディオムのように見えますが、私はMac OS X上でこれが動作するかどうか、そして/またはあなたがルートアクセス権を持っていないかどうかはわかりません。あなた自身のcrontabファイルのエントリに相当するものがありますか? – dreeves

+0

コマンドラインで "ps auxwww | grep meh"を実行すると、返されます。 --- usersname 2803 0.0 0.0 61156 724 pts/0 SN + 06:19 0:00 grep meh --- そのcronが本当に作品はどうですか?それはcronからの出力ではありませんか? – joedevon

+0

あなたはpsの出力を取得しようとしていません。そのため、/ dev/nullにリダイレクトします。 grepはps出力にSCRIPTNAMEが存在するかどうかを確認しています。存在する場合は0を返し、そうでない場合は0を返します。 || SCRIPTNAMEは、grepがゼロ以外を返す場合にのみ実行され、コマンドを開始します。 –

0

を私は、データベースから読み取るためにPHPベースのスクリプトを使用します(PEAR Mail_Queueライブラリを使用して)電子メールを送ります。私はbashスクリプトの中から実行し、返された結果( "exit $ status;")に基づいて停止するか、X秒間スリープさせるか、すぐに再起動します。 (また、私は負荷平均/睡眠のチェックをPHPスクリプトに入れて、メールシステムに負荷をかけないようにします)。

継続的に実行しなければならない長期デーモンの場合は、これを実行するのが最良の方法ではないと思います(ただし、長期的に正常に実行されたソケットサーバーについて聞いたことがありますが)しかし、PHP 5.3ではガベージコレクションが改善されました。スクリプトが計画外に終了しないように十分に書かれていれば、メモリはこれまでよりもはるかに少ない問題になるはずです。

3

私たちは、メールに出力をパイプによって、私たちのデーモンを実行します。デーモンが停止した場合、それはメールを送信し、我々はそのように通知されます/

php daemon.php | mail -s "daemon stopped" [email protected] 

その方法、。

もちろん、デーモンを手動で再起動することを意味しますが、すぐにわかります。通常、デーモンが停止した場合は、とにかく処理する必要のあるものがあることを意味します。通常は大丈夫です。

+0

'stderr'を' stdout'にリダイレクトし、パイプの前に '2>&1'を使ってメールすることもできます。 –

0

私はPHPがこれのための最良のツールではないことに同意しますが、データベースアクセスなどのアプリケーションからコンポーネントを再利用できるように、なぜPHPを使用するのか理解できます。

私は同様の問題があり、PHPスクリプトを実行できるCで書かれたデーモンであるThe Fat Controllerを開発しました。また、スクリプトの多くのインスタンスを並行して実行して、マルチスレッドデーモンとして実行することもできます。

詳細と使用例はここにあります:http://www.4pmp.com/fatcontroller/

1

デーモンはバックグラウンドで実行されるLinuxプロセスです。 apacheまたはmysqlはデーモンです。 Linux環境では、cronjobを使ってバックグラウンドプログラムを実行できますが、いくつかの制限がありますが、いくつかのシナリオでは良い考えではありません。 たとえば、cronjobを使用して、前回の実行がまだ終了していないかどうかを制御することはできません。 プロセスをデーモンとして実行するほうが便利なことがよくあります。

// Daemonize 
$pid = pcntl_fork(); // parent gets the child PID and child gets 0 
if($pid){ // if pid is not 0 
    // Only the parent will know the PID. Kids aren't self-aware 
    // Parent says goodbye! 
    print "Parent : " . getmypid() . " exiting\n"; 
    exit(); 
} 
print "Child : " . getmypid() . "\n"; 

上記のコードはPHPでデーモンを作成する方法については非常に良い記事から取られています。あなたはこれを読むことができますlink

関連する問題