Python 芹菜2个不同代码源的实例

Python 芹菜2个不同代码源的实例,python,django,celery,Python,Django,Celery,我有两种工人: 第一类链接到django进行db轮询 第二种,与django没有任何交互 我使用rabbitMQ作为代理,第一次在同一台服务器上启动这两种worker 我希望将第1类和第2类之间的代码分开,以便将来能够在单独的服务器中启动workers。我希望避免在运行第二种辅助程序的服务器中使用django代码 在django worker方面,我对它们的定义如下: @shared_task(name='task_polling') def task_polling(): send_t

我有两种工人:

  • 第一类链接到django进行db轮询
  • 第二种,与django没有任何交互
  • 我使用
    rabbitMQ
    作为代理,第一次在同一台服务器上启动这两种worker

    我希望将第1类和第2类之间的代码分开,以便将来能够在单独的服务器中启动workers。我希望避免在运行第二种辅助程序的服务器中使用django代码

    在django worker方面,我对它们的定义如下:

    @shared_task(name='task_polling')
    def task_polling():
        send_task('do_work', [], {'_serialized_task': serialized_task})
    
    @shared_task(name='save_shell_task')
    def save_shell_task(_result):
        pass
    
    $ celery -A tasks worker --loglevel=info -Q task_workers_queue
    $ celery -A ussd_auto worker -B -l info -Q db_workers_queue
    
    和以下芹菜配置:

    from __future__ import absolute_import
    
    import os
    from datetime import timedelta
    from celery import Celery
    
    
    # set the default Django settings module for the 'celery' program.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ussd_auto.settings.local')
    
    
    app = Celery(include=[
        'app_task_management.tasks',
    ])
    
    app.conf.update(
        CELERY_IGNORE_RESULT=True,
        CELERY_ACCEPT_CONTENT=['json'],
        CELERY_TASK_SERIALIZER='json',
        CELERYBEAT_SCHEDULE={
            'periodic_task': {
                'task': 'task_polling',
                'schedule': timedelta(seconds=1),
            },
        },
    )
    
    我使用以下命令启动这些worker:

    celery -A my_app worker -B -l info
    
    在启动屏幕上,任务已正确注册:

     -------------- celery@mbp-de-julio.home v3.1.12 (Cipater)
    ---- **** -----
    --- * ***  * -- Darwin-13.1.0-x86_64-i386-64bit
    -- * - **** ---
    - ** ---------- [config]
    - ** ---------- .> app:         __main__:0x102341390
    - ** ---------- .> transport:   amqp://guest:**@localhost:5672//
    - ** ---------- .> results:     disabled
    - *** --- * --- .> concurrency: 4 (prefork)
    -- ******* ----
    --- ***** ----- [queues]
     -------------- .> celery           exchange=celery(direct) key=celery
    
    
    [tasks]
      . save_shell_task
      . task_polling
    
     -------------- celery@mbp-de-julio.home v3.1.12 (Cipater)
    ---- **** -----
    --- * ***  * -- Darwin-13.1.0-x86_64-i386-64bit
    -- * - **** ---
    - ** ---------- [config]
    - ** ---------- .> app:         tasks:0x101833450
    - ** ---------- .> transport:   amqp://guest:**@localhost:5672//
    - ** ---------- .> results:     disabled
    - *** --- * --- .> concurrency: 4 (prefork)
    -- ******* ----
    --- ***** ----- [queues]
     -------------- .> celery           exchange=celery(direct) key=celery
    
    
    [tasks]
      . do_work
    
    另一方面,我定义了任务和芹菜配置,如下所示:

    from celery import Celery
    from celery import shared_task
    from celery.execute import send_task
    
    from task_workers import task_workers
    
    app = Celery('tasks', broker='amqp://guest@localhost//')
    
    @shared_task(name='do_work')
    def do_work(_serialized_task):
        result = task_workers.Worker().do(_task=_serialized_task)
        send_task('save_shell_task', [], {'_result':result})
    
    我使用以下命令启动此工作程序:

        celery -A tasks worker --loglevel=info
    
    “开始”屏幕显示任务已正确注册:

     -------------- celery@mbp-de-julio.home v3.1.12 (Cipater)
    ---- **** -----
    --- * ***  * -- Darwin-13.1.0-x86_64-i386-64bit
    -- * - **** ---
    - ** ---------- [config]
    - ** ---------- .> app:         __main__:0x102341390
    - ** ---------- .> transport:   amqp://guest:**@localhost:5672//
    - ** ---------- .> results:     disabled
    - *** --- * --- .> concurrency: 4 (prefork)
    -- ******* ----
    --- ***** ----- [queues]
     -------------- .> celery           exchange=celery(direct) key=celery
    
    
    [tasks]
      . save_shell_task
      . task_polling
    
     -------------- celery@mbp-de-julio.home v3.1.12 (Cipater)
    ---- **** -----
    --- * ***  * -- Darwin-13.1.0-x86_64-i386-64bit
    -- * - **** ---
    - ** ---------- [config]
    - ** ---------- .> app:         tasks:0x101833450
    - ** ---------- .> transport:   amqp://guest:**@localhost:5672//
    - ** ---------- .> results:     disabled
    - *** --- * --- .> concurrency: 4 (prefork)
    -- ******* ----
    --- ***** ----- [queues]
     -------------- .> celery           exchange=celery(direct) key=celery
    
    
    [tasks]
      . do_work
    
    但似乎芹菜的两个例子不知道如何沟通:

    [2014-07-09 22:21:52,184: ERROR/MainProcess] Received unregistered task of type u'task_polling'.
    The message has been ignored and discarded.
    
    Did you remember to import the module containing this task?
    Or maybe you are using relative imports?
    Please see http://bit.ly/gLye1c for more information.
    
    The full contents of the message body was:
    [...]
    KeyError: u'task_polling'
    
    如何在两侧配置芹菜以解决通信问题

    2007年10月更新

    当我单独使用轮询任务启动beat时,轮询正在工作,但当我与其他工作人员一起启动芹菜时,芹菜收到轮询消息,并说他不知道此任务。也许我必须为任务赋予不同的队列属性

    我定义了队列

    在worker kind 2一侧,celeryconfig.py文件:

    CELERY_ROUTES = {
        'do_work': {
            'queue': 'task_workers_queue'
        },
        'task_polling': {
            'queue': 'db_workers_queue'
        },
        'save_shell_task': {
            'queue': 'db_workers_queue'
        },
    }
    
    在db工人类别1侧:

    app.conf.update(
        CELERY_IGNORE_RESULT=True,
        CELERY_ACCEPT_CONTENT=['json'],
        CELERY_TASK_SERIALIZER='json',
        CELERYBEAT_SCHEDULE={
            'periodic_task': {
                'task': 'task_polling',
                'schedule': timedelta(seconds=1),
            },
        },
        CELERY_ROUTES={
            'task_polling': {
                'queue': 'db_workers_queue'
            },
            'save_shell_task': {
                'queue': 'db_workers_queue'
            },
            'do_work': {
                'queue': 'task_workers_queue'
            }
        },
    )
    
    我推出的芹菜是这样的:

    @shared_task(name='task_polling')
    def task_polling():
        send_task('do_work', [], {'_serialized_task': serialized_task})
    
    @shared_task(name='save_shell_task')
    def save_shell_task(_result):
        pass
    
    $ celery -A tasks worker --loglevel=info -Q task_workers_queue
    $ celery -A ussd_auto worker -B -l info -Q db_workers_queue
    
    现在,周期性任务
    db_polling
    被beat很好地调用。 此任务成功地将作业发送到
    do\u work
    任务。 但是
    do\u work
    task未能将结果发送到任务
    save\u shell\u task

    没有错误,但没有附加任何内容。

    在第一次尝试中,您在同一个代理上配置了两个工作进程,但注册的任务不同。 在第一个场景中,2名工作人员将从代理接收循环任务,这就是为什么出现第一个错误:

    Received unregistered task of type u'task_polling'.
    
    对于第二个没有注册此任务的工作人员来说,这是显而易见的,他实际上不知道源代码

    在您的更新中,您从逻辑上考虑为每个工作人员创建专用队列,这无疑是一个适当的解决方案,可以避免工作人员执行不应该从代理获得的任务。 您只犯了一个错误,Cellery send_任务方法将不关心路由,这是一种只向代理发送api和AMQP消息的方式,在通过任务类调度任务时考虑了路由。 要使其正常工作,您需要以以下方式在send task方法中指定队列:

    send_task('save_shell_task', [], kwargs={'_result':result, queue=queue})
    
    有关此主题的更多信息:

    希望这有帮助