什么是异步
程序是自上而下一行一行执行的,第二行需要第一行执行完成才能开始执行,如果某一行的程序执行时间需要很长,比如说一些音视频的上传,短信和邮件的发送,那么程序将阻塞在这一行。
异步就是当某一行程序执行的时候,即使需要很长的时间,第二行也能够立即执行。
什么是 Celery
通俗来说,Celery 是 Python 的一个异步队列服务器。在我们日常web应用中,请求一个后端接口就是等待该接口的业务完成后再返回,如果接口执行的任务很耗时,就会造成服务阻塞甚至请求超时,
而前端又需要及时地给出响应,那么这种情况,就可以将耗时的任务交给异步队列服务器去处理。
比如在一个用户注册场景中,保存了用户账号和密码就可以立即返回,如果等到激活邮件发送成功再返回,这可能需要几秒钟时间,这样的用户体验就不太好了,所以这个邮件的发送就可以用异步的形式去处理。
Celery 的使用场景
异步任务:将耗时操作任务提交给Celery去异步执行。
定时任务:比如每日数据统计
Celery 的基本结构
task producer:任务生产者,产生任务并交给任务队列
celery beat:任务调度器,周期性地将配置中需要执行的任务发送给任务队列(定时任务)
borker:任务队列,介于生产者和消费者的中间人,就是生产者存放和消费者拿取任务的地方
celery 本身不提供队列服务,一般用 redis 来充当 broker 的角色
worker:任务消费者,它会实时监控队列,如果有任务就拿出来执行
result:储存任务结果的地方
Celery 的一个简单应用
这里我用redis作为broker,需要提前安装redis和celery并启动redis服务。
1.写一个task
#tasks.py
import time
from celery import Celery
#配置Celery的backend和broker
broker = 'redis://localhost:6379/1'
backend = 'redis://localhost:6379/2'
#创建Celery实例
app = Celery('my_task',broker=broker,backend=backend)
@app.task
def add(x,y):
print('enter func...')
time.sleep(5) #模拟耗时操作
return x + y
2.启动Worker
在cmd里面启动Worker,监听 Broker 中是否有任务
命令:celery worker -A tasks -l INFO
-A: 指定 celery 实例在哪个模块中,这里实例在tasks.py文件中,启动成功后,能看到一下信息
现在 Broker 中还没有任务,worker 相当于待命状态
3.调用任务
新建一个 trigger.py 文件,调用刚刚被装饰的函数。将任务发送给 Broker,
#trigger.py
import time
from tasks import add
def trigger():
t1 = time.time()
print('start task...')
result = add.delay(4,7) #这里需要用 celery 提供的接口 delay 进行调用
print('end task...')
print(result)
t2 = time.time()
print('共耗时:%s' % str(t2 - t1))
if __name__ == '__main__':
trigger()
运行 trigger.py
程序花了 0.1s 执行完成,如果按照同步逻辑去走,至少需要 5s 时间
在worker窗口看日志信息:
小tips:Celery4.x 开始不再支持Windows,如果要在Windows开发,需要使用3.x的版本。