芹菜工人从哪个目录开始

时间:2019-05-24 02:56:32

标签: python celery celery-task celeryd

我需要有关芹菜工人的帮助。我尤其无法理解celery worker命令需要从何处(哪个目录)执行,其背后的概念是什么,以及与导入有关的一些事情。

所以说我有以下目录结构:

.
├── __init__.py
├── entry.py
├── state1
│   ├── __init__.py
│   ├── family1
│   │   ├── __init__.py
│   │   ├── task1.py
│   │   ├── task2.py
│   │   └── task3.py
│   └── family2
│       ├── __init__.py
│       └── task1.py
└── state2
    ├── __init__.py
    ├── family1
    │   ├── __init__.py
    │   ├── task1.py
    │   └── task2.py
    └── family2
        ├── __init__.py
        ├── task1.py
        └── task2.py

.是当前工作目录,名为project

每个taskn.py(task1.py,task2.py等)都是单独的任务。每个任务文件如下所示:

from celery import Celery
from celery.result import AsyncResult
from kombu import Queue

_name_ = "project_x"
celapp=Celery(backend='redis://localhost:6379/0', broker='amqp://a:b@localhost/a_vhost')
CELERY_CONFIG = {
    'CELERY_DEFAULT_QUEUE': 'default',
    'CELERY_QUEUES': (Queue('q1'), Queue('q2'),),
    'CELERY_TASK_SERIALIZER': 'pickle',
    'CELERY_ACCEPT_CONTENT': ['json','pickle']
}

celapp.conf.update(**CELERY_CONFIG)

@celapp.task()
def t1():
    print("starting task")
    time.sleep(5)
    print("Finished task")

以下是entry.py的内容:

import json
from flask_cors import CORS
from flask import Flask, Response, render_template
from flask import request, jsonify, redirect
from functools import wraps
<what would be the import statement to import all the tasks>

_name_ = "project_x"
app     = Flask(_name_)

@app.route("/api1", methods=['POST'])
def api1():
    req = request.jsonify
    if not req:
        return jsonify(success=False, msg="Missing request parameters", code="1")
    else:
        param1 = req.get('p1')
        param2 = req.get('p2')
        tId = startTask()
        return jsonify(success="True", msg="All Good", taskId=tId)


def startTask():
    tId = "abcd123"
    created_task = state1.family1.task1.subtask(queue='q1')
    created_task.delay()
    return tId


if __name__ == '__main__':
    app.run(debug=True, host="192.168.1.7", port="4444")

entry.py是烧瓶应用程序,将从中触发api1,然后根据我要启动特定任务的参数进行操作。

现在这是我的问题:

  1. entry.py文件中的所有任务导入的导入语句
  2. 我从哪里开始工作。我的意思是我应该从哪个目录启动Celery -A <directory name> worker -l info命令,为什么?
  3. 在许多示例中,我看到任务和CeleryApp文件之间存在明显的隔离。有人可以建议一下安排我的任务,芹菜配置等更好的方法吗,以上两个问题将如何与这个新提议的结构保持一致?

2 个答案:

答案 0 :(得分:1)

好的,希望这会有所帮助。我会按照您的要求相反地答复。

  

在许多示例中,我看到任务之间存在明显的隔离   和CeleryApp文件。有人可以建议会是什么   安排我的任务,芹菜配置等的更好方法,以及如何   以上两个问题与这个新提议的结构相符吗?

我在添加的代码片段中遇到的第一个问题,即您拥有的每个taskn.py都有自己的celery实例。您需要在每个taskn.py之间共享该实例。 我推荐的是创建一个celery_app.py

my_app
├── __init__.py
├── entry.py
├── celery_app.py
│   ├── ...

在此文件中,您将创建celery实例

from celery import Celery
from celery.result import AsyncResult
from kombu import Queue

_name_ = "project_x"
celapp=Celery(backend='redis://localhost:6379/0', broker='amqp://a:b@localhost/a_vhost')
CELERY_CONFIG = {
    'CELERY_DEFAULT_QUEUE': 'default',
    'CELERY_QUEUES': (Queue('q1'), Queue('q2'),),
    'CELERY_TASK_SERIALIZER': 'pickle',
    'CELERY_ACCEPT_CONTENT': ['json','pickle']
}

celapp.conf.update(**CELERY_CONFIG)
celery_app.conf.imports = [
    'state1.family1.task1',
    'my_app.state1.family1.task2',  # Or Maybe
    ...
]

然后您可以在每个taskn.py中导入该实例,并且每个任务都将在同一celery应用程序下注册

from my_app.celery_app import celapp

@celapp.task()
def t1():
    print("starting task")
    time.sleep(5)
    print("Finished task")
  

我从哪里开始工作。我的意思是我应该从哪个目录   启动Celery -A worker -l info命令,为什么?

然后,您应该轻松调用Celery -A my_app.celery_app worker -l info,因为您的celery实例将位于模块my_app和celery_app子模块中

  

什么是导入条目中的所有任务的导入语句。py

最后从entry.py开始,您可以执行import state1.family1.task1 import t1并要求t1.delay()或任何已注册的任务。

答案 1 :(得分:0)

因此,按照@Patricio的建议,似乎确实是导入错误。我的新目录结构如下所示:

.
├── __init__.py
├── celeryConfig
│   ├── __init__.py
│   └── celeryApp.py
├── entry.py
├── state1
│   ├── __init__.py
│   ├── family1
│   │   ├── __init__.py
│   │   ├── task1.py
│   │   ├── task2.py
│   │   └── task3.py
│   └── family2
│       ├── __init__.py
│       └── task1.py
└── state2
    ├── __init__.py
    ├── family1
    │   ├── __init__.py
    │   ├── task1.py
    │   └── task2.py
    └── family2
        ├── __init__.py
        ├── task1.py
        └── task2.py

celeryConfig/celeryApp.py的内容如下:

from celery import Celery
from celery.result import AsyncResult
from kombu import Queue

_name_ = "project_x"
celapp=Celery(backend='redis://localhost:6379/0', broker='amqp://a:b@localhost/a_vhost', include=['state1.family1.task1'])
CELERY_CONFIG = {
    'CELERY_DEFAULT_QUEUE': 'default',
    'CELERY_QUEUES': (Queue('q1'), Queue('q2'),),
    'CELERY_TASK_SERIALIZER': 'pickle',
    'CELERY_ACCEPT_CONTENT': ['json','pickle']
}

celapp.conf.update(**CELERY_CONFIG)

和taskn.py的内容类似:

from celeryConfig.celeryApp import celapp
import time

@celapp.task()
def t1():
    print("starting task")
    time.sleep(5)
    print("Finished task")

entry.py保持原样,仅作如下更改:

from state1.family1.task1 import t1

现在芹菜开始时为: 来自根目录celery -A celeryConfig.celeryApp worker -l info的{​​{1}},一切正常。作为上述命令的输出,我得到的消息为

project

表示芹菜已正确启动,并且该任务确实已注册。因此,现在,为了注册所有任务,我可以通读目录/目录并在. . . [tasks] . state1.family1.task1.t1 . . . 中动态创建include列表。 (一旦完成,将发布更多有关此内容的信息)

感谢@Patricio