python2处理耗时任务_异步任务利器—Celery

「1.什么是celery」

celery是基于python实现的一个分布式任务队列框架,主要用于管理分布式任务队列、处理耗时的任务,支持使用任务队列的方式执行任务调度。可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行,通常使用它实现异步任务和定时任务。

「2.celery架构」

celery的架构由三部分组成:

  1. 消息中间件(broker)

任务调度队列,用于存放task,接收任务生产者发来的消息(即任务),将任务tasks存入队列。Celery 本身不提供队列服务,但是可以方便的和第三方提供的消息中间件集成,官方推荐使用 RabbitMQ 和 Redis

  1. 任务执行单元(worker)

Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它

  1. 任务执行结果存储(backend)

Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等

6c6904b666557fa5898bf5ea1181c082.png
celery架构图

「3.celery中的任务task」

任务模块(tasks)-- 用户定义的函数,用于实现应用功能,比如执行一个发送短信的耗时任务.它包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列

「4.celery 优点」

简单:一旦熟悉了celery的工作流程后,配置和使用是比较简单的。

高可用:当任务执行失败或执行过程中发生连接中断,Celery 会自动尝试重新执行任务。

快速:一个单进程的Celery每分钟可处理上百万个任务。

「5.celery适用场景」

异步任务:将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等

定时任务:Celery任务队列支持定时触发,可以按照时间间隔或者crontab表达式来触发任务定时执行某件事情,比如每天数据统计


「5.celery使用案例」

celery配置文件config.py

# coding: utf-8
from celery import Celery

celery_broker = 'amqp://guest@127.0.0.1//'
celery_backend = 'amqp://guest@127.0.0.1//'

# Add tasks here
CELERY_IMPORTS = (
    'tasks',
)

app = Celery('celery', broker=celery_broker, 
backend=celery_backend, include=CELERY_IMPORTS)

app.conf.update(
    CELERY_ACKS_LATE=True,  # 允许重试
    CELERY_ACCEPT_CONTENT=['pickle', 'json'],
    CELERY_TASK_SERIALIZER='json',
    CELERY_RESULT_SERIALIZER='json',
    # 设置并发worker数量
    CELERYD_CONCURRENCY=4, 
    # 每个worker最多执行500个任务被销毁,可以防止内存泄漏
    CELERYD_MAX_TASKS_PER_CHILD=500, 
    BROKER_HEARTBEAT=0,  # 心跳
    CELERYD_TASK_TIME_LIMIT=12 * 30,  # 超时时间
)

# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = True
# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'sub': {
        'task': 'tasks.sub',
        'schedule': timedelta(seconds=3),
        # 每周一早八点
        # 'schedule': crontab(hour=8, day_of_week=1), 
        'args': (300, 150),
    }
}

tasks.py

#coding=utf-8
from config import app
from celery.signals import worker_process_init, worker_process_shutdown

@worker_process_init.connect
def init_worker(*args, **kwargs):
    # 初始化资源
    pass

@worker_process_shutdown.connect
def release_worker(*args, **kwargs):
    # 释放资源
    pass


# 普通函数装饰为 celery task
@app.task
def add(x, y):
    return x + y

@app.task
def sub(x, y):
    return x - y


main.py

#coding=utf-8

import time
from tasks import add

if __name__ == '__main__':
    a = time.time()
    # delay与apply_async生成的都是AsyncResult对象
    async = add.apply_async((1, 100))
    if async.successful():
        result = async.get()
        print(result)
    elif async.failed():
        print('任务失败')
    elif async.status == 'PENDING':
        print('任务等待中被执行')
    elif async.status == 'RETRY':
        print('任务异常后正在重试')
    elif async.status == 'STARTED':
        print('任务已经开始被执行')


tornado中使用celery

# encoding:utf8
import tcelery
import tornado.gen
import tornado.web
import tornado.ioloop
from tasks import add

tcelery.setup_nonblocking_producer()

class CheckHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        x = int(self.get_argument('x', '1'))
        y = int(self.get_argument('y', '2'))
        response = yield tornado.gen.Task(add.apply_async, args=[x, y])
        self.write({'results': response.result})
        self.finish()

if __name__ == "__main__":
    print 'start'
    application = tornado.web.Application([
        (r"/add", CheckHandler),
    ])
    application.listen(8889)
    tornado.ioloop.IOLoop.instance().start()
    print 'end'


「6.celery的启动」

celery -A config tasks --loglevel=info

启动完毕后执行main.py可以看到celery的日志 如图:dc131d62f5c8c0f63d7cec4dcec096ee.png

让我们一起探索未知的世界~,如果对你有启发和帮助,帮忙点赞和转发。感谢~

想要学习更多干货,赶紧关注公众号噢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值