@更新: 将任务从shared_task更改为app.celeryd.celery.task可解决此问题。是否有一些其他设置可以使shared_tasks正常工作?
完全重写仍然是相同的错误。我会尽量使其相对较短。新的项目结构更加简洁,外观如下:
proj
|-- app
| |-- controller
| | |-- __init__.py
| | +-- greeting_model.py
| |-- model
| | |-- __init__.py
| | +-- dto
| | |-- __init__.py
| | +-- greeting_dto.py
| |-- service
| | |-- __init__.py
| | +-- greeting_service.py
| |-- tasks
| | |-- __init__.py
| | +-- greeting_tasks.py
| |-- __init__.py
| |-- celeryd.py
| +-- flaskd.py
|-- test.py
|-- worker.py
+-- ws.py
我正在分别初始化celery和flask,并提供worker.py,它将在客户端计算机上运行,而ws.py(flask Web服务)将在另一个计算机上运行。 Celery初始化非常简单,并且将rpc后端与RabbitMQ代理一起使用。目前,这2个队列是静态的,但稍后将从配置中填充它们。
from kombu import Queue
from celery import Celery
celery = Celery('LdapProvider',
broker='amqp://admin:passwd@localhost:5672/dev1',
backend='rpc',
include=['app.tasks.greeting_tasks'])
celery.conf.task_queues = (
Queue("q1", routing_key="c1.q1"),
Queue("q2", routing_key="c2.q2"),
)
Worker.py(用于启动celery worker-此问题过于简化):
from app.celeryd import celery as celery
from celery.bin.worker import worker
if __name__ == '__main__':
celeryd = worker(app=celery)
options = {
'broker': 'amqp://admin:passwd@localhost:5672/dev1',
'queues': 'q1',
'loglevel': 'info',
'traceback': True
}
celeryd.run(**options)
我将省略烧瓶初始化,并跳转到greeting_service.py,它调用celery任务:
# greeting_service.py:
from app.celeryd import celery
from app.tasks.greeting_tasks import say_hello
class GreetingService(object):
def say_hello(self, name: str) -> str:
async_result = say_hello.apply_async((name,), queue='q1')
return async_result.get()
# greeting_tasks.py
from celery import shared_task
@shared_task(bind=True)
def say_hello(self, name: str) -> str:
return name.capitalize()
无论我如何尝试,该调用都无法通过烧瓶。我创建了test.py只是为了测试芹菜是否可以正常工作:
from app.celeryd import celery
from app.tasks.greeting_tasks import say_hello
if __name__ == '__main__':
async_result = say_hello.apply_async(('jackie',), queue='q1')
print(async_result.get())
与greeting_service.py几乎相同,只是没有从flask_restplus名称空间的greeting_controller中调用。 test.py的区别在于:
/home/pupsz/PycharmProjects/provider/venv37/bin/python /home/pupsz/PycharmProjects/provider/test.py
Jackie
Process finished with exit code 0
[2020-01-16 18:56:17,065: INFO/MainProcess] Received task: app.tasks.greeting_tasks.say_hello[bb45e271-563e-405b-8529-7335a3810976]
[2020-01-16 18:56:17,076: INFO/ForkPoolWorker-2] Task app.tasks.greeting_tasks.say_hello[bb45e271-563e-405b-8529-7335a3810976] succeeded in 0.010257695998006966s: 'Jackie'
通过烧瓶我得到的所有信息已经显示,并且工作日志未显示任何传入的任务,这意味着通过烧瓶Apply_async没有将任务发送到RabbitMQ:
File "/home/xyz/PycharmProjects/proj/app/service/greeting_service.py", line 8, in say_hello
return async_result.get()
NotImplementedError: No result backend is configured.
Please see the documentation for more information.
我在django中发现了一个类似的问题,但没有答案,所以我有些困惑,希望能得到一些指导。
答案 0 :(得分:0)
解决方案:在此处回答了使shared_task正常工作的解决方案:LINK 将celerz初始化修改为:
from kombu import Queue
from celery import Celery
celery = Celery('LdapProvider',
broker='amqp://admin:passwd@localhost:5672/dev1',
backend='rpc')
# include=['app.tasks.greeting_tasks'])
celery.conf.task_queues = (
Queue("q1", routing_key="c1.q1"),
Queue("q2", routing_key="c2.q2"),
)
celery.set_default()
即使我要删除注释掉的include行,工作人员也会成功拾取app.tasks.greeting_tasks中定义的shared_task:
[tasks]
. app.tasks.greeting_tasks.say_hello
将应用程序设置为default_app()之后,即使使用shared_task时也不会再引发NotImplementedError。至于原因...我不知道,这是6个小时的反复试验,经历了不同的配置和谷歌搜索。在某些更复杂的情况下,我发现官方文档没有任何帮助。