Celery(1)

基础
0)安装celery模块
pip3 install celery
1)创建一个celery application 用来定义你的任务列表
from celery import Celery app = Celery('tasks', #tasks 也就是在worker端执行的一个APP,这个app里做些任务,跟django APP一样的道理,,名字随意起 broker='redis://localhost', #broker是中间商,队列. worker通过队列拿到任务,然后去执行 backend='redis://localhost') #执行完任务后,你必须告诉celery,需要把结果写到哪里 @app.task def add(x,y): print("running...",x,y) return x+y
2) 启动Celery Worker来开始监听并执行任务
celery -A test1 worker -l debug #-A 你的py脚本,别加后缀 #worker 角色。有很多, #-l 日志级别 也有很多
当执行完毕后会有如下这些信息

---app就是你定义的tasks
---transport:就是你的中间商 broker
---results: 后续再说
---concurrency: 现在是一个进程可以同时执行2个任务
--------->>你的worker就已经启动了------->启动之后,就得等着执行任务--->等待有人往队列中放任务!!
试着启动ipython来测试一下各种方法
1)入门
In [1]: import test1 In [2]: a=test1.add.delay(5,6) #执行worker In [3]: a.get() #同步拿结果 Out[3]: 11 In [4]:
2) 如果增加time.sleep()
@app.task def remove(x,y): time.sleep(5) print("running...x-y",x,y) return x-y
#检查任务是否已完成
#当你返回true的时候,再去取值。就不会卡主 In [19]: t=test1.remove.delay(9,5) In [20]: t.ready() Out[20]: False In [21]: t.ready() Out[21]: False In [22]: t.ready() Out[22]: True In [23]: t.get() Out[23]: 4
3)可以设置超时时间
t.get(timeout=5) #设置超时时间。如果在这个时间段没有获得值,就返回一个 TimeoutError: The operation timed out. 错误
4)如果你的app内有错误的内容话
如果你代码有错,
@app.task def remove(x,y): time.sleep(5) print(name) #不存在会报错 print("running...x-y",x,y) return x-y
那你希望只希望打印错误就行,不要导致worker有异常
那你需要!这样
get(
propagate=False
)
In [8]: t.get(propagate=False) Out[8]: celery.backends.base.NameError("name 'name' is not defined")
#打印错误的详细信息 In [9]: t.traceback Out[9]: 'Traceback (most recent call last):\n File "/usr/local/lib/python3.5/site-packages/celery/app/trace.py", line 367, in trace_task\n R = retval = fun(*args, **kwargs)\n File "/usr/local/lib/python3.5/site-p
项目中如何使用celery
可以把celery配置成一个应用
mkdir celery_pro
celery_pro/celery.py内容
from __future__ import absolute_import, unicode_literals# 从你安装的程序下,绝对路径下导入celery from celery import Celery app = Celery('proj', broker='redis://localhost', backend='redis://localhost', include=['celery_pro.tasks','celery_pro.tasks2']) #把app交给celery去管理 # Optional configuration, see the application user guide. app.conf.update( result_expires=3600, #你的消息存入redis里面.如果一个小时没有人取就会丢弃掉 ) if __name__ == '__main__': app.start()
在创建一个task 文件
tasks.py
from __future__ import absolute_import, unicode_literals from .celery import app @app.task def add(x, y): return x + y @app.task def mul(x, y): return x * y @app.task def xsum(numbers): return sum(numbers)
tasks2.py
from __future__ import absolute_import, unicode_literals from .celery import app import time,random @app.task def number(start,end): time.sleep(3) return random.randint(start,end)
启动worker
celery -A celery_pro worker -l debug ###这里就不是py文件。是你的项目名字
###就会打印出你的tasks
[tasks]
. celery.accumulate
. celery.backend_cleanup
. celery.chain
. celery.chord
. celery.chord_unlock
. celery.chunks
. celery.group
. celery.map
. celery.starmap
. celery_pro.tasks.add
. celery_pro.tasks.mul
. celery_pro.tasks.xsum
. celery_pro.tasks2.number
##执行任务的时候,你不能进去项目去执行
在ipython中操作
In [1]: from celery_pro import tasks,tasks2 In [2]: t=tasks.add.delay(5,5) In [3]: t.get() Out[3]: 10 In [9]: t=tasks2.number.delay(10,1000000000) In [10]: t.get() Out[10]: 800914092
接下来测试分布式的功能
当你同时启动2个woker进程时,,
你去发放任务,
In [15]: t=tasks2.number.delay(10,50) In [16]: t.get() Out[16]: 26
那这2个worker进程就会去队列中取,谁先拿到就去执行, 然后返回 ---就实现了分布式的效果了,你的任务越多,建立更多的worker进程就可以了
后台启动你的worker
celery multi start w1 -A celery_pro -l info #w1 :是给你的worker起个名字 #-A 是项目名字 #-l 日志级别
##那就是这样显示
[root@linux-node1 soft]# celery multi start w1 -A celery_pro -l debug celery multi v4.0.2 (latentcall) > Starting nodes... > w1@linux-node1: OK
如果你想实现分布式,那你在另外一台机器也起一个woker进程----都能连上redis就可以
[root@linux-node1 soft]# celery multi start w2 -A celery_pro -l debug celery multi v4.0.2 (latentcall) > Starting nodes... > w2@linux-node1: OK [root@linux-node1 soft]#
如果你需要重启 ---这w1,w2 都需要存在一台机器上
restart | stop 都是可以的
[root@linux-node1 soft]# celery multi restart w1 w2 -A celery_pro celery multi v4.0.2 (latentcall) > Stopping nodes... > w1@linux-node1: TERM -> 8985 > w2@linux-node1: TERM -> 9024 > Waiting for 2 nodes -> 8985, 9024...... > w1@linux-node1: OK > Restarting node w1@linux-node1: OK > Waiting for 2 nodes -> None, None.... > w2@linux-node1: OK > Restarting node w2@linux-node1: OK > Waiting for 1 node -> None... [root@linux-node1 soft]#

浙公网安备 33010602011771号