16

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

ありがとう。

4

3 に答える 3

14

定義した関数を実行する cron ジョブを設定するか、より高度でおそらく推奨される方法として、セロリをプロジェクトに統合することができます (これは実際には非常に簡単です)。

于 2011-06-30T09:38:24.797 に答える
11

最初にインポートするときに、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()

これが機能するには、デーモン プロセスを 1 つだけ使用する必要があります。そうしないと、各プロセスがおそらく望ましくない同じことを行ってしまいます。

デーモン プロセス グループで複数のプロセスを使用している場合、別の方法として、このバックグラウンド スレッドを実行することのみを目的とする特別なデーモン プロセス グループを作成します。つまり、プロセスは実際にはリクエストを受け取りません。

これを行うには、次のものが必要です。

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

WSGIImportScript ディレクティブは、プロセス グループ「django-jobs」のコンテキストで、そのスクリプトをロードし、起動時に実行するように指示します。

複数のスクリプトを保存するために、WSGIScriptAlias に使用した元の WSGI スクリプト ファイルを指定しました。ただし、そのディレクティブによってロードされたときに実行したくないので、次のようにします。

import mod_wsgi

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

ここでは、デーモン プロセス グループの名前を調べ、このためだけに単一のプロセスでセットアップされた特別なデーモン プロセス グループ内で起動された場合にのみ実行されます。

全体として、すでに堅牢であることが知られているものではありますが、Apache を大きな栄光のプロセス マネージャーとして使用しているだけです。このプロセスは、リクエストの受け入れと処理に加えて追加のメモリを消費するため、少しやり過ぎですが、実行している内容の複雑さによっては、それでも有用な場合があります。

これを行うことの 1 つの良い点は、まだ完全な 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 は「django-site」で実行され、/admin は「django-jobs」で実行されます。

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

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

于 2011-06-30T10:05:01.227 に答える
0

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

セロリは行く方法です。さらに、長い非同期プロセスをタスク化できるため、リクエスト/レスポンス時間を短縮できます。

于 2011-07-05T01:28:58.527 に答える