Django構成celery(非djcelery)非同期タスクとタイミングタスクの実行

5829 ワード

すべてのプレゼンテーションはDjango 2に基づく.0
Celeryはpythonに基づいて開発された簡単で柔軟で信頼性の高い分散型タスクキューフレームワークであり、タスクキューを使用して分散型のマシン/プロセス/スレッド上でタスクスケジューリングを実行することをサポートします.典型的な生産者-消費者モデルを採用し、主に3つの部分から構成されている.
  • メッセージキューbroker:brokerは実際にはMQキューサービスであり、redis、rabbitmqなどをbroker
  • として使用することができる.
  • タスクを処理する消費者workers:brokerはworkerキューにタスクがあることを通知し、workerはキューからタスク実行を取り出し、各workerはプロセス
  • である.
  • 結果を格納backend:実行結果はbackendに格納され、デフォルトではbrokerが使用するMQキューサービスに格納されますが、どのサービスでbackend
  • を行うかを個別に構成することもできます.
    非同期タスク
    私の非同期の使用シーンはプロジェクトのオンラインになります:フロントエンドのwebの上で1つのオンラインボタンがあって、ボタンをクリックした后にバックエンドに要求を出して、バックエンドはオンラインの过程を実行して5分要して、バックエンドは要求を受信した后にタスクをキューに入れて非同期に実行して、同时にすぐにフロントエンドの1つのタスクの実行の中の结果に戻ります.非同期実行がなければどうなるのでしょうか.同期の場合は、実行中にフロントエンドがバックエンドから結果を返すのを待っていたため、ページの回転や回転がタイムアウトしてしまいます.
    非同期タスク構成
    1.rabbitmqをインストールします.ここではrabbitmqをbrokerとして使用します.インストールが完了するとデフォルトで起動します.他の構成も必要ありません.
    # apt-get install rabbitmq-server

    2.celeryのインストール
    # pip3 install celery

    3.celeryはdjangoプロジェクトで使用され、djangoプロジェクトディレクトリ構造(簡略化)は以下の通りである.
    website/
    |-- deploy
    |   |-- admin.py
    |   |-- apps.py
    |   |-- __init__.py
    |   |-- models.py
    |   |-- tasks.py
    |   |-- tests.py
    |   |-- urls.py
    |   `-- views.py
    |-- manage.py
    |-- README
    `-- website
        |-- celery.py
        |-- __init__.py
        |-- settings.py
        |-- urls.py
        `-- wsgi.py
    

    4.website/celery.pyプライマリファイルの作成
    from __future__ import absolute_import, unicode_literals
    import os
    from celery import Celery, platforms
    
    # set the default Django settings module for the 'celery' program.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'website.settings')
    
    app = Celery('website')
    
    # Using a string here means the worker don't have to serialize
    # the configuration object to child processes.
    # - namespace='CELERY' means all celery-related configuration keys
    #   should have a `CELERY_` prefix.
    app.config_from_object('django.conf:settings', namespace='CELERY')
    
    # Load task modules from all registered Django app configs.
    app.autodiscover_tasks()
    
    #   root     celery
    platforms.C_FORCE_ROOT = True
    
    @app.task(bind=True)
    def debug_task(self):
        print('Request: {0!r}'.format(self.request))

    5.website/__init__.pyファイルに以下の内容を追加し、django起動時にこのappが
    from __future__ import absolute_import
    
    # This will make sure the app is always imported when
    # Django starts so that shared_task will use this app.
    from .celery import app as celery_app
    
    __all__ = ['celery_app']

    6.各アプリケーションはtasksを作成する.pyファイル、ここではdeploy/tasks.py
    from __future__ import absolute_import
    from celery import shared_task
    
    @shared_task
    def add(x, y):
        return x + y
  • 注意tasks.pyは各appのルートディレクトリの下に構築する必要があり、tasksと呼ぶしかない.py、勝手に
  • と命名することはできません
    7.views.pyでの参照このtasks非同期処理の使用
    from deploy.tasks import add
    
    def post(request):
        result = add.delay(2, 3)
  • は、関数名を用いる.delay()は、関数を非同期で
  • 実行することができる.
  • は、result.ready()によって、タスクが処理を完了するか否かを判断することができる
  • .
  • タスクが例外を放出する場合、result.get(timeout=1)を使用して例外
  • を再放出できます.
  • タスクが例外を投げ出す場合、result.tracebackを使用して元の遡及情報
  • を取得することができる.
    8.celeryの起動
    # celery -A website worker -l info

    9.postというメソッドを呼び出すと、中のaddは非同期で処理できます.
    タイミングタスク
    タイミングタスクの使用シーンは一般的です.例えば、ボスにタイミングよく報告する必要があります.
    タイミングタスク構成
    1.website/celery.pyファイルタイミングタスクcrontabをサポートする構成を追加
    from celery.schedules import crontab
    
    app.conf.update(
        CELERYBEAT_SCHEDULE = {
            'sum-task': {
                'task': 'deploy.tasks.add',
                'schedule':  timedelta(seconds=20),
                'args': (5, 6)
            }
            'send-report': {
                'task': 'deploy.tasks.report',
                'schedule': crontab(hour=4, minute=30, day_of_week=1),
            }
        }
    )
  • は、2つのtaskを定義します.
  • 「sum-task」という名前のtaskは、20秒ごとにadd関数を実行し、2つのパラメータ5と6
  • を伝えた.
  • 'send-report'という名前のtaskは、毎週朝4:30にreport関数
  • を実行します.
  • timedeltaはdatetimeのオブジェクトであり、from datetime import timedeltaの導入が必要であり、以下のいくつかのパラメータがある.
  • days:日
  • seconds:秒
  • microseconds:微妙
  • milliseconds:ミリ秒
  • minutes:分
  • hours:時間
  • crontabのパラメータは次のとおりです.
  • month_of_year:月
  • day_of_month:日付
  • day_of_week:週
  • hour:時間
  • minute:分

  • 2.deploy/tasks.pyファイルreportメソッドの追加:
    @shared_task
    def report():
        return 5

    3.celery beatを起動し、celeryはbeatプロセスを起動し、タスクが実行される必要があるかどうかを絶えず判断している.
    # celery -A website beat -l info

    Tips
    1.非同期タスクと計画タスクを同時に使用する場合は、ワークとbeatを同時に起動できるcelery -A website worker -b -l infoのより簡単な起動方法があります.rabbitmqをキューとして使用しない場合は、次のようにメインプロファイルのwebsite/celery.pyでbrokerとbackendを構成する必要があります.
    # redis MQ  
    app = Celery('website', backend='redis', broker='redis://localhost')
    # rabbitmq MQ  
    app = Celery('website', backend='amqp', broker='amqp://admin:admin@localhost')

    3.celeryがrootユーザーで起動できない場合は、メインプロファイルにplatforms.C_FORCE_ROOT = Trueを追加する必要があります.Celeryは長時間の運転後にメモリ漏れが発生する可能性があり、ワークごとにどれだけのタスクを実行して死んだかを示す構成CELERYD_MAX_TASKS_PER_CHILD = 10を追加する必要があります.
    参考記事:
  • http://docs.celeryproject.org/en/latest/
  • https://github.com/pylixm/celery-examples
  • https://pylixm.cc/posts/2015-12-03-Django-celery.html