二、py方式用celery
一、创建项目
- 项目启动文件
from __future__ import absolute_import #未来文件绝对入口,必须每个模块顶部启用 from celery import Celery app=Celery('pj', include=['celery_project.tasks'] ) #从config.py中导入配置文件 app.config_from_object('celery_project.config') if __name__ == '__main__': app.start()#运行celery
- 配置项
from __future__ import absolute_import #用redis的第10个库存放任务执行结果 CELERY_RESULT_BACKEND='redis://127.0.0.1/10' #用redis的第11个库做消息代理 BROKER_URL='redis://127.0.0.1/11' #add方法的任务放for_add队列中 #subtract方法的任务放for_subtract队列中 CELERY_ROUTES={ 'tasks.add':{'queue':'for_add','routing_key':'for_add'}, 'tasks.subtract':{'queue':'for_subtract','routing_key':'for_subtract'}, }
CELERY_RESULT_BACKEND:存储任务执行结果
BROKER_URL:用于消息传输,代理人
CELERY_ROUTES:用于任务路由,即什么任务放什么队列中,即由什么worker来处理
这里外层字典的key(tasks.add和tasks.subtract)与下文中的测试无关,只有队列名称在添加任务的时候需要明确指定放入那个队列,否则默认放在了celery队列 - 任务处理,一个函数对应一个任务
from __future__ import absolute_import #从我们自己的celery中引入app from celery_project.celery import app #定义一个减法方法 @app.task def add(x,y): return int(x)+int(y) #定义一个加法方法 @app.task def subtract(x,y): return x-y
- 。
二、启动项目
- 启动
(3.6env) huangya:~/code/ubuntu$ celery -A celery_project worker -Q for_add -l info -------------- celery@huangya v4.2.1 (windowlicker) ---- **** ----- --- * *** * -- Linux-4.4.0-43-Microsoft-x86_64-with-Ubuntu-18.04-bionic 2018-12-03 21:39:10 -- * - **** --- - ** ---------- [config] - ** ---------- .> app: pj:0x7f30ad1de6a0 - ** ---------- .> transport: redis://127.0.0.1:6379/11 - ** ---------- .> results: redis://127.0.0.1/10 - *** --- * --- .> concurrency: 4 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> for_add exchange=for_add(direct) key=for_add [tasks] . celery_project.tasks.add . celery_project.tasks.subtract [2018-12-03 21:39:39,691: INFO/MainProcess] Connected to redis://127.0.0.1:6379/11 [2018-12-03 21:39:39,718: INFO/MainProcess] mingle: searching for neighbors [2018-12-03 21:39:40,754: INFO/MainProcess] mingle: all alone
-A:项目名称
-Q:队列名称,默认队列是celery,可以用逗号分隔同时处理多个队列
-l:日志级别 - 交互模式下添加任务
(3.6env) huangya@HUANGYA:~/code/ubuntu$ python Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from celery_project.tasks import add,subtract >>> add.apply_async((1,2),queue='for_add') <AsyncResult: 49c3ee99-a163-4a27-99ca-a9794d6aec39> >>>
- 前台查看任务执行情况
- 在redis数据库中查看消息结果,任务id是一一对应的
- 添加任务不指定queue,默认添加到了celery队列
>>> add.apply_async((2,3)) <AsyncResult: 9a140be6-8bbe-4897-9763-edcdbdb42794> >>>
- 由于任务没有处理,我们可以在消息代理人中查看
- ###############################################用crontab方式定时生产任务,并让worker去执行,我们可以用celery的beat去做###############################################
- 如每隔1分钟执行任务,需要配置
timezone = "Asia/Shanghai"
from __future__ import absolute_import from datetime import timedelta from celery.schedules import crontab CELERY_RESULT_BACKEND='redis://127.0.0.1/10' BROKER_URL='redis://127.0.0.1/11' CELERY_ROUTES={ 'add':{'queue':'for_add','routing_key':'for_add'}, 'subtract':{'queue':'for_subtract','routing_key':'for_subtract'}, } CELERYBEAT_SCHEDULE={ 'add':{ 'task':'celery_project.tasks.add', 'schedule':crontab(minute='*/1'), #'schedule':timedelta(minute=1), 'args':(10,10) } }
CELERYBEAT_SCHEDULE中可以同时定义多个任务,crontab的精度无法精确到秒时可使用timedelta实现
task:任务单元导入名,如这里的add
schedule:具体调度
args:任务单元执行参数 - 启动beat:celery -A celery_project beat -l info
- 启动worker:celery -A celery_project worker -l info
- 给定时任务指定queue
CELERYBEAT_SCHEDULE={ 'add':{ 'task':'celery_project.tasks.add', 'schedule':crontab(minute='*/1'), 'args':(10,10), 'options':{'queue':'for_add'}, } }
- 启动worker并指定queue为for_add,celery -A celery_project -Q for_add worker -l info。正常启动beat,celery -A celery_project beat -l info
- 以上即可使用beat定时任务,合并命令
celery -B -A celery_project -Q for_add worker
- 以后台任务运行celery multi start cleery_test -B -A celery_project -Q for_add worker -l info
- 关闭后台进程celery multi stop celeery_test -A celery_project,实际测试并没有关闭,尴尬
- celery multi其他方法