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]# 

 

posted @ 2017-07-11 00:32  所有的梦想都画在墙上  阅读(340)  评论(0)    收藏  举报