最初にインポートするときに、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 ジョブから実行するコマンド ライン スクリプトを用意することです。コマンド ライン スクリプトは、時折の一時的なメモリ使用量を意味しますが、毎回すべてをロードする必要があるため、ジョブの起動コストが高くなります。