サードパーティAPIを使用したり、メールを送信したり、ビデオを変換したりなど、多くの外部コンポーネントにアクセスする必要があるスケーラブルなシステムを設計する場合、これを実装する最良の方法は、すべてのシステムコンポーネントの相互作用の接続リンクであるキューイングシステムを使用した非同期モデルです。
Pythonで最も人気のあるキューシステムはCeleryであり、幅広いタスク管理機能を備えています。 残念ながら、Celeryベースのシステムは保守が難しく、何か問題が発生した場合、問題を見つけることは非常に困難です。 あなたはどんな開発者にもセロリの経験について尋ねることができますが、あまり良くない言葉を聞く準備ができています。
幸いなことに、代替ソリューション-uWSGIスプーラーがあります。この記事では、これについて詳しく説明します。
Celeryとの主な違いは、追加のコンポーネント(Celery自体とストレージ(Redisなど))を使用する必要がないため、障害ポイントの数が2つ減ることです。 タスクストアとして、ディレクトリ、外部ディレクトリ、またはネットワークプールを使用できます。
Pythonプログラムを制御するために、しばしばuWSGIを使用します。 なんで? 構成が簡単で、信頼性が高く、柔軟性があり、ほとんどの要件を満たすためです。
Webアプリケーションへの継続的なアクセスという形でPythonコードを提供することに加えて、uWSGIには、キューシステムを実装するスプーラーコンポーネントも含まれています。 スプーラーにはいくつかの機能があり、そのドキュメントはかなり不足しています。
uWSGIスプーラーの使用は簡単で、1つ2つ3つです! しかし、いくつかのニュアンスがあります。
uwsgiモジュールはコードからインポートできないため、コンソールからコードをテストすることはできません。設定を作成する必要があるたびにuwsgiワーカーを実行する必要があります。
[uwsgi] socket = /var/run/mysite.sock master = True processes = 4 project_dir = /home/myuser/mysite chdir = %(project_dir) spooler = /var/uwsgi_spools/mysite_spool spooler-import = path.to.spool.package # (package to import spool file) spooler-frequency = 10 # Frequency for scanning spool max-requests = 5000 module = wsgi:application touch-reload = wsgi.py
ワーカーファイル:
from uwsgidecorators import spool, uwsgi @spool def my_func(args): print(args) # do some job
コードからの問題のステートメント:
import uwsgi_spools.mysite_spool as mysite_spool mysite_spool.my_func.spool(test=True)
この例からわかるように、使用するエントリのしきい値は非常に低くなっています。
タスク内では、3つのサービスキー(関数名ud_spool_func 、 タスク名spooler_task_name、 タスクステータスud_spool_ret )およびタスクの作成時に渡されたすべてのパラメーター(例ではテストキー)を含む辞書を含む1つの引数を使用できます。
タスクは次の3つのステータスを返すことができます。
- -2(SPOOL_OK)-タスクは完了し、キューから削除されます。
- -1(SPOOL_RETRY)-何か問題が発生しました。タスクが再度呼び出されます。
- 0(SPOOL_IGNORE)-タスクを無視します。
他のすべての値は-1(SPOOL_RETRY)として解釈されます。
機能:関数が例外で失敗しなかった場合、 @spool
デコレータ@spool
1回実行されます(SPOOL_OKを返します)。
ライフサイクルを管理するには、 @spoolraw
を使用する必要があります。
タスクを作成するときの特別なキー(補助):
- スプーラー -タスクを実行するスプーラーへの絶対パス。
- at -unix time、タスクを完了する必要があるとき(より正確には、この値より前に完了することはありません)。
- priority-タスクフォルダー内のサブフォルダーを示します(より多くのワーカーをそのようなサブフォルダーに割り当てることができます)。--spooler-orderedを使用して、優先順位を構成できます。
- body-このキーは64 KBを超える値に使用され、タスクはシリアル化された形式で使用できます。
@spool
デコレータに加えて、 @spool
デコレータ@spool
使用できます。これは引数として秒数を取り、指定された間隔で装飾された関数を実行できるようにします。
@timer(30) def my_func(args): print(args) # do some job every 30 sec
@timer
同様に、関数の実行(ステータスSPOOL_RETRYのタスクの完了)を再開する@timer
デコレーターがあります。
@spoolforever def my_func(args): print(args) # do some job and repeat
ネットワーク上で作業するようにワーカーを構成するには、使用可能なアドレスをiniファイルに追加する必要があります。
socket = 127.0.0.1:10001
タスクを作成するときに、タスク受信者のアドレスを指定します。
uwsgi.send_message(“127.0.0.1:10001”, 17, 0, test=True, 5) # uwsgi.spool(test=True, spooler=“127.0.0.1:10001”)
したがって、uWSGIスプーラーはキューの代替として使用できますが、機会がまだない場合や少し砂糖が必要な場合は、不足しているものを実装するuwsgi-tasksを使用できます。