1.
不用filter=task_method时,实例(self)不会自动传入。
只有bind=True时, task对象会作为第一个参数自动传入。
加上filter=task_method参数,实例(self)会作为第一个参数自动传入。
加上filter=task_method, bind=True, task对象会作为第一个,实例(self)会作为第二个参数自动传入。
所以,最佳调用方式应为:
from celery.contrib.methods import task_method
class A(object):
def __init__(self):
object.__init__(self)
self.a = 1
self.b = 2
@app.task(bind=True, filter=task_method)
def test1(task_self, self, a, b):
print a
print b
return a+b+self.a+self.b
2.
在task中实现单例资源,缓存:
from celery import Task
class DatabaseTask(Task):
_db = None
@property
def db(self):
if self._db is None:
self._db = Database.connect()
return self._db
@app.task(base=DatabaseTask)
def process_rows():
for row in process_rows.db.table.all():
process_row(row)
3.
路由必须使用Exchange,不然无反应
CELERY_QUEUES = (
Queue('downloader', Exchange('down_consumer', type='direct'), routing_key='downloader'))
CELERY_ROUTES = {
'task.downloader': {'exchange': 'down_consumer', 'routing_key': 'downloader'})
4.
celery -A app worker,app 为目录时 目录下必须有celery.py,多个app仅指定路由 仍会接受到其他消息,必须指定队列。
5.
分离的worker尽量使用send_task,否则代码混乱,link error问题,线程循环问题loop异常使用:
from gevent import monkey, sleep
monkey.patch_all()