celery异步任务处理

一、异步任务

异步任务是web开发中一个很常见的方法。对于一些耗时耗资源的操作,往往从主应用中隔离,通过异步的方式执行。
运用场景:注册的功能,在用户使用邮箱注册成功之后,需要给该邮箱发送一封激活邮件。如果直接放在应用中,则调用发邮件的过程会遇到网络IO的阻塞,比较好的处理方式则是使用异步任务,将发邮件从主业务中解耦出来,应用在业务逻辑中触发一个异步任务。

二、生产者消费者模式

模式
生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
生产者消费者模式面向过程的一种编程模式。在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。

三、celery

celery是基于python实现的一个异步任务的调度工具,同时还是一个任务队列,主要用于处理耗时的任务。
celery本身不含消息服务,需要依赖一个消息队列MQ来来传递任务,客户端代码只需要向MQ中派发任务,Celery进程就可以从MQ中读取消息并派发给worker,从而达到了客户端程序与Celery进程解耦的效果。而且Celery进程并不需要监听任何端口,减少了配置的复杂性。目前,Celery支持的消息服务有RabbitMQ、Redis甚至是数据库,当然Redis应该是最佳选择。

(1)celery架构

celery架构由三个模块组成:消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
celery构成
消息中间件(Broker): 消息中间人,是任务调度队列,是一个独立的服务,是一个生产者消费者模式,生产者把任务放入队列中,消费者(worker)从任务队列中取出任务执行,任务的执行可以按照顺序依次执行也可以按照计划时间进行。但是Broker本身不提供队列服务,所以要集成第三方队列,推荐使用RatbbitMQ或Redis.

任务执行单元(worker):即执行任务的程序,可以有多个并发。它实时监控消息队列,获取队列中调度的任务,并执行它。

任务执行结果存储(task result store):由于任务的执行同主程序分开,如果主程序想获取任务执行的结果,就必须通过中间件存储。同消息中间人一样,存储也可以使用RabbitMQ、Redis;另外,假如不需要保存执行的结果也可以不配置这个模块。

(2)celery特点

  • 简单:Celery 易于使用和维护,并且它不需要配置文件
  • 高可用性:倘若连接丢失或失败,进程和客户端会自动重试,并且通过主/主或主/从方式复制来提高可用性
  • 快速:单个 Celery 进程每分钟可处理数以百万计的任务,而保持往返延迟在亚毫秒级
  • 灵活:Celery 几乎所有部分都可以扩展或单独使用。可以自制连接池、序列化、压缩模式、日志、调度器、消费者、生产者、自动扩展、中间人传输或更多。

(3)工作原理

它的基本工作就是管理分配任务到不同的服务器,并且取得结果。至于说服务器之间是如何进行通信的?这个Celery本身不能解决。所以,RabbitMQ作为一个消息队列管理工具被引入到和Celery集成,负责处理服务器之间的通信任务。和rabbitmq的关系只是在于,celery没有消息存储功能,他需要介质,比如rabbitmq、redis、mysql、mongodb 都是可以的。

(4)celery应用

安装:

  • 用pip安装:$ pip install -U Celery
  • 用easy_install 安装:$ easy_install -U Celery
  • 捆绑式安装:$ pip install celery[librabbitmq] 或者 $ pip install
    celery[librabbitmq,redis,auth,msgpack]。
    步骤:
    ①执行任务单元 task.py

task.py中

from celery import Celery
import time 

# broker和backend都设置为redis
my_task = Celery('task',broker='redis://127.0.0.1:6379/1',
    backend='redis://127.0.0.1:6379/2')

# 任务执行单元
@my_task.task
def func1(x,y):
    time.sleep(10)
    return x + y

② 派送任务 handle.py

from task import func1

res = func1.delay(2,4)   #  用delay去向执行单元派送任务并传参
print(res.id)

③先运行worker,让他处于ready状态,如果有数据就可以直接处理数据:

celery worker -A task -l INFO

# -A 指定worker所在的Celery app的文件名,就是task
# -l   是日志打印的级别
# -c 10 可以同时开启10个worker处理 

# 运行结果
[tasks]
  . task.func1

[2019-05-20 16:37:28,752: INFO/MainProcess] Connected to redis://127.0.0.1:6379//
[2019-05-20 16:37:28,768: INFO/MainProcess] mingle: searching for neighbors
[2019-05-20 16:37:29,797: INFO/MainProcess] mingle: all alone
[2019-05-20 16:37:29,841: INFO/MainProcess] celery@hjj-virtual-machine ready.

④运行我们的发送命令的 handle.py

python3 handle.py

参考:
https://www.jianshu.com/p/1840035cb510
https://www.cnblogs.com/pythonlyz/p/10325640.html
https://www.cnblogs.com/jimmyhe/p/10895742.html

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值