首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

分布式任务队列 Celery—应用基础

前言

分布式任务队列 Celery,Python 后端技能树必点。结合 RabbitMQ 系列,深入梳理 Celery 知识点。当然,这也会是一个系列的文章。

简介

Celery 是一个简单、灵活且可靠的分布式任务队列(Distributed Task Queue)。队列是一种常见的数据结构,具有 FIFO(First in First Out)的特性,阻塞队列能够有效的将应用程序解耦为生产者和消费者,从而实现异步调用。任务的主体是被 celery.task 装饰器包装过的函数,而在队列中传递的 “任务” 其实是执行这些函数所需要的全部参数。

首先需要明确的是,Celery 虽然称之为分布式任务队列,但其本身并不提供队列服务,它更像是队列的 Controller,而非队列本身。所以应用 Celery 还需要集成第三方的消息队列中间件(e.g. RabbitMQ or Redis)。

那 Celery 和 RabbitMQ 有什么区别呢?简单来说 RabbitMQ 专注于消息队列的管理,而 Celery 专注于实时的任务处理。

Celery 的应用场景

即时响应需求

网页的响应时间是用户体验的关键,Amazon 曾指出响应时间每提高 100ms,他们的收入便会增加 1%。对于一些需要长时间执行的任务,大多会采用异步调用的方式来释放用户操作。Celery 的异步调用特性,和前端使用 Ajax 异步加载类似,能够有效缩短响应时间。

周期性任务需求(Periodic Task)

对于心跳测试、日志归档、运维巡检这类指定时间周期执行的任务,可以应用 Celery 任务调度模块 Celery Beat,支持 crontab 定时模式,简单方便。

高并发及可扩展性需求

解耦应用程序最直接的好处就是可扩展性和并发性能的提高。Celery 支持以多线程、多进程、协程的方式来并发执行任务,同时支持自动动态扩展。

架构组成

Broker

消息代理,作为临时储存任务的中间媒介,为 Celery 提供了队列服务。生产者将任务发送到 Broker,消费者再从 Broker 获取任务。

Beat

任务调度器,负责调度并触发 Celery 定时周期任务。Beat 进程读取 CeleryConfig 中自定义的定时周期任务列表,将到期需要执行的定时任务发送到任务队列中。

Worker

任务执行单元,实际负责执行任务的服务进程,每一个 Worker 都有一个并发池(Prefork/Eventlet/Gevent/Thread)来支持多并发。Worker 会监听订阅的任务队列,当队列中有任务时,就会获取任务并执行。

Result Backend/Store

任务执行状态和结果存储,Celery 支持任务实时处理,也就是说 Celery 可以把任务执行的实时状态和最终结果回传生产者。这种回传也需要通过中间存储媒介。

Celery 应用基础

先通过一个简单的例子来认识 Celery,这里使用 RabbitMQ 充当 Broker,使用 Redis 充当 Result Backend。

Step1:安装 Celery & RabbitMQ & Redis

Step2:初始化 Celery Proj 项目

Step3:配置 Celery Config

Step4:实现 App Factory

Step5:实现 Celery Runner

Step6:实现 Celery Tasks

Step7:启动 Celery Worker

选项,指定 Celery 的项目,如果参数是一个 Package,那么 celery cmd 会自动搜索 celery.py 模块。当然了,你也可以使用 app 所在的 module_name 作为参数。celery cmd 最终要加载的实际上是 app 对象。

Step7:执行任务

NOTE:想要获取任务执行结果必须启用 Result Backend,否则会触发异常

Step8:自定义 Exchange & Queue

自定义 Exchange 和 Queue 需要依赖 kombu 库,kombu 是一个「Messaging library for Python」,Python 写的消息库。目标是为 AMQP 协议提供高层接口,让 Python 的消息传递尽可能变得简单,并且也提供一些常见的消息传递问题解决方案。

Step9:指定任务队列

NOTE:apply_async & delay

使用 app.task 装饰器包装函数以后,得到的实际上是一个类对象,而非单纯的函数,所以我们能够通过函数来调用 delay/apply_async 方法。当调用这两个方法时,才实际触发了一个任务。而如果直接调用该函数的话,那么跟调用一个普通函数没有区别。

JmilkFan-范桂飓

专注于 Python、云计算与大数据

技术即沟通

下一位 offer 达人,就是你 !!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180115G05Y8X00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券