7

Rails アプリからのプロセスを「バックグラウンド」にするために fork{} を使用するのが良いアイデアかどうかについて、いくつか考えてみたいと思います...

私が集めたものから fork{my_method; Process#setsid} は、実際に本来の機能を果たします。

1) 異なる PID を持つ別のプロセスを作成します

2) 呼び出しプロセスを中断しません (たとえば、フォークの終了を待たずに続行します)。

3) 終了するまで子を実行します

..これはクールですが、それは良い考えですか? フォークは正確に何をしているのですか?Rails mongrel/passenger インスタンス全体の複製インスタンスがメモリ内に作成されますか? もしそうなら、それは非常に悪いでしょう。それとも、大量のメモリを消費することなく、どうにかしてそれを行うのでしょうか。

私の最終的な目標は、バックグラウンドのデーモン/キュー システムを廃止して、これらのプロセス (主に電子メールの送信) をフォークすることでした。しかし、これでメモリが節約されない場合は、間違いなく間違った方向への一歩です。

4

3 に答える 3

5

フォークはプロセス全体のコピーを作成し、アプリケーションサーバーへの接続方法に応じて、そのコピーも作成します。他の議論で述べたように、これはコピーオンライトで行われるので、許容範囲内です。結局のところ、Unixはfork(2)を中心に構築されているため、かなり高速に管理する必要があります。部分的にバッファリングされたI/O、開いているファイル、およびその他の多くのものもコピーされ、それらを書き出すためにスプリングロードされたプログラムの状態もコピーされることに注意してください。これは正しくありません。

私はいくつかの考えを持っています:

  • アクションメーラーを使用していますか?Process.popenメールはAMや何かで簡単にできるようです。(Popenはフォークを実行しますが、直後にexecが続きます。)
  • Process.exec別のrubyインタープリターと機能を実行して、その状態をすぐに取り除きます。転送する状態が多すぎる場合、またはこれらの複製されたファイル記述子を実際に使用する必要がある場合は、IO#popen代わりに次のようなことを行って、サブプロセス作業を送信することができます。システムは、サブプロセスのRubyインタープリターのテキストを含むページを親と自動的に共有します。
  • daemons上記に加えて、 gemの使用を検討することをお勧めします。railsプロセスはすでにデーモンですが、gemを使用すると、1つのバックグラウンドタスクをバッチジョブサーバーとして実行し続けることが容易になり、起動、監視、爆破した場合の再起動、および起動時のシャットダウンが容易になる場合があります。 。
  • fork(2)edサブプロセスを終了する場合は、exit!代わりにを使用してくださいexit
  • あなたのように、メッセージキューとデーモンがすでに設定されていることは、私にとっては良い解決策のように思えます:-)
于 2009-10-15T00:16:57.797 に答える
1

fork() は (まだ) 実装されていないため、Rails で JRuby を使用できなくなることに注意してください。

于 2009-10-15T04:57:22.440 に答える
0

forkのセマンティクスは、プロセスのメモリスペース全体を新しいプロセスにコピーすることですが、多くの(ほとんどの?)システムは、仮想メモリテーブルのコピーを作成し、コピーオンライトとしてマークするだけでそれを実行します。つまり、(少なくとも最初は)それほど多くの物理メモリを使用せず、新しいテーブルやその他のプロセスごとのデータ構造を作成するのに十分です。

とはいえ、RubyやRoRなどがコピーオンライトフォークとどれだけうまく相互作用するかはわかりません。特に、ガベージコレクションは、多くのメモリページにアクセスする(コピーされる)場合に問題になる可能性があります。

于 2009-10-14T18:53:08.717 に答える