我有两种工人:
我使用rabbitMQ
作为代理,并在同一服务器上第一次启动两种工作者。
我想将kind 1和kind 2之间的代码分开,以便将来能够在分离的服务器中启动worker。我想避免运行第二种工作者的服务器中的django代码。
在django工作者方面,我将它们定义为:
@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
以下芹菜配置:
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),
},
},
)
我使用以下命令启动这些工作程序:
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
另一方面,我定义了任务和芹菜配置:
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})
我使用此命令启动此worker:
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: 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'
如何在两侧配置芹菜来解决通信问题?
更新10/07
当我单独使用轮询任务启动节拍时,轮询正在进行,但当我与其他工作人员一起启动芹菜时,这个芹菜收到了轮询的消息,并说他不知道这个任务。也许我必须为任务分配不同的队列?
我定义了队列。
在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 worker kind 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'
}
},
)
我像这样推出了这样的画廊:
$ celery -A tasks worker --loglevel=info -Q task_workers_queue
$ celery -A ussd_auto worker -B -l info -Q db_workers_queue
现在,周期性任务db_polling
可以通过节拍很好地调用。
此任务成功将作业发送到do_work
任务。
但do_work
任务未能将结果发送到任务save_shell_task
。
没有错误,但没有任何附加。
答案 0 :(得分:0)
在第一次尝试中,您在同一个代理上配置了两个工作但具有不同的注册任务。 在第一个场景中,2个工作人员将从经纪人那里以循环方式接收任务,说明为什么会出现第一个错误:
Received unregistered task of type u'task_polling'.
对于没有注册此任务的第二名工作人员来说,显而易见并期望他实际上并不知道源代码。
在您的更新中,您在逻辑上考虑为每个工作者创建专用队列,这肯定是一个正确的解决方案,以避免工作人员承担它不应该从代理获得的任务。 你只做了一个错误,芹菜send_task方法不会关心路由,这种方式只是一个api发送和AMQP消息给代理,路由是在通过任务类调度任务时考虑到的。 要使其工作,您需要以这种方式在发送任务方法中指定队列:
send_task('save_shell_task', [], kwargs={'_result':result, queue=queue})
有关该主题的更多信息:
希望这有帮助