celery 各种坑

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()

猜你喜欢

转载自my.oschina.net/phybrain/blog/1619051