2011-06-30 7 views
14

私はmod_wsgiを使用してApache経由でdjangoサイトを提供しています。私はまた、バックグラウンドプロセス(dameon?)として実行されるいくつかのPythonコードを持っています。サーバーをポーリングし、データをDjangoモデルの1つに挿入します。これは正常に動作しますが、私はこのコードを私のDjangoアプリケーションの一部にすることができますが、常にバックグラウンドで実行することができますか?それはプロセスそのものではなく、常にアクティブなDjangoサイトの芸術である必要はありません。もしそうなら、これを達成するのに役立つ例やドキュメントに私を指摘できますか?デーモンのようにDjango内でコードを実行することはできますか?

ありがとうございました。

答えて

14

定義した関数を実行するcronジョブを設定するか、より高度で推奨される方法で、celeryをプロジェクトに組み込むことができます(これは実際には簡単です)。

+0

私はセロリーと一緒に行きました。魅力のように働いた。 –

+0

cronタスクはバックグラウンドで継続的に実行されませんが、所定の時間に開始し、準備ができたら終了します。 django-commandsは起動するのに1.5秒かかります(モデルの複雑さに依存しています)。これは通常、高性能が必要なときに行う方法ではありません。 – FeedTheWeb

+0

これはまだ有効ですか?はいの場合、長い処理を行うセロリのタスクをデモンストレーションする良い方法は何でしょうか? –

9

WSGIスクリプトを最初にインポートするときに、バックグラウンドスレッドを作成することができます。あなたがそうでない場合、各プロセスは、おそらくしたくない同じことをやっているだろう唯一のデーモンプロセスを使用しなければならないのに、これが機能するために

import threading 
import time 

def do_stuff(): 
    time.sleep(60) 
    ... do periodic job 

_thread = threading.Thread(target=do_stuff) 
_thread.setDaemon(True) 
_thread.start() 

デーモンプロセスグループで複数のプロセスを使用している場合は、このバックグラウンドスレッドを実行する目的だけの特別なデーモンプロセスグループを作成することもできます。言い換えれば、プロセスは実際には要求を受け取っていません。

あなたが持っていることによってこれを行うことができます:

WSGIDaemonProcess django-jobs processes=1 threads=1 
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django-jobs application-group=%{GLOBAL} 

をWSGIImportScriptディレクティブは、そのスクリプトをロードし、プロセスグループ「ジャンゴ・ジョブ」のコンテキストで起動時にそれを実行すると言います。

複数のスクリプトを保存するために、WSGIScriptAliasに使用したオリジナルのWSGIスクリプトファイルを指摘しました。私たちは、それはしかしそのディレクティブによってロードされたとき、それは実行したくないので、私たちは行います

import mod_wsgi 

if mod_wsgi.process_group == 'django-jobs': 
    _thread = threading.Thread(target=do_stuff) 
    _thread.setDaemon(True) 
    _thread.start() 

ここでは、デーモン・プロセス・グループの名前を見て、特別なデーモンプロセス内で起動したときにのみ実行されますグループはこれのためだけに単一のプロセスで設定します。

全体として、堅牢であることは既に知られていますが、全体的に見ても、プロセス管理者としてはApacheを使用しているだけです。このプロセスでは、要求を受け入れて処理する要求の上に追加のメモリが消費されるため、少し複雑ですが、実行している処理の複雑さにもよりますが、依然として有効です。

これは、まだ完全なDjangoアプリケーションであるため、特定のURLをこのプロセスだけにマップすることができ、バックグラウンドタスクを管理または監視するためのリモートAPIを提供することができます。 。

ここ
WSGIDaemonProcess django-jobs processes=1 threads=1 
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django-jobs application-group=%{GLOBAL} 

WSGIDaemonProcess django-site processes=4 threads=5 
WSGIScriptAlias//usr/local/django/mysite/apache/django.wsgi 

WSGIProcessGroup django-site 
WSGIApplicationGroup %{GLOBAL} 

<Location /admin> 
WSGIProcessGroup django-jobs 
</Location> 

、「ジャンゴ・ジョブ」で/ adminを使用「ジャンゴ・サイトの中/管理の実行、下のものを除くすべてのURL。

とにかく、要求通りにApache mod_wsgiデーモンプロセス内でそれを行う特定の問題に対処しています。

指摘したように、別の方法として、Djangoを設定して読み込み、cronジョブから作業を実行して実行するコマンドラインスクリプトを使用する方法があります。コマンドラインスクリプトは一時的なメモリ使用を意味しますが、毎回すべてをロードする必要があるため、ジョブの起動コストが高くなります。

+0

+1 slick私はmod_wsgiがこれに対する答えを持っているか分からなかった。 –

+0

Gunicornを使用している場合は、Gunicornの 'when_ready'関数をオーバーライドして新しいスレッドを開始できます。次に例を示します:https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py –

+0

メモリからは、 '' when_ready''がgunicornの親プロセスで実行されます。このような親プロセスで長時間実行することは一般的には良い考えではありません。その親プロセスはフォークされてワーカープロセスになり、バックグラウンドスレッド自体がフォークを生き残ることはできなくても、バックグラウンドスレッドによって引き起こされた状態を引き継ぐことには意味があります。 –

0

以前はcronジョブを使用していましたが、私はあなたにしばらくしてセロリーに切り替えます。

セロリが行く道です。さらに、長い非同期処理を行うことで、要求/応答時間を短縮することができます。

関連する問題