celery 进阶使用篇

celery 进阶使用篇,第1张

一、前言

之前讲了 celery 的基本使用,这篇文章主要用于记录一些使用心得,涉及到的概念相对比较底层,面试时候也经常会问到这一块的内容。主要包括 4 个方面,celery worker 模式、celery 工作流、celery 任务调起常用参数、回调函数

二、celery worker 模式

为什么 worker 要有多种工作模式呢,因为异步任务类型也不一样,有的偏计算密集型,有的偏 IO 密集型。

一般 worker 的工作模式主要有三种,第一个种是 prefork,多进程模式,每启动一个 worker 就是多开启一个进程,使用于计算密集型的任务类型。第二种是 evenlet, 第三种是 gevent,这两种模式下 worker 是协程启动的,所以适用于 IO 密集型的异步任务。

三、celery 工作流

有的时候异步任务需要按照一定的顺序串行执行,这个时候就需要考虑 celery 的执行顺序了。我说一下自己所了解的 3 种工作流方式, group 工作组,chain 工作链, chord 复合任务

顾名思议,group 工作组就是一组任务,可以并行执行,chain 工作链就是可以实现工作任务按照一定顺序串行执行,chord 复合任务是因为有了一个回调函数,在一组任务并行执行之后,再串行执行回调函数,所以串并复合,同时也可以拿到各个并行任务的执行结果。

四、apply_async 常用参数

五、回调函数

当异步任务执行完成之后,可以使用回调函数记录任务执行结果

我把在v2上发的帖子下面的评论摘抄下来

原帖: https://www.v2ex.com/t/593748#r_7793688

两个说的比较详细的回答:

回答1:

一个工厂(worker)有一个员工(单进(线)程),为了提高效率,请多了几个员工一起工作(单 worker 多进程)

为了防止这个工厂断电无法工作,那么多建了几个工厂,每个工厂有多个员工(多 worker 多进程)

实际上都是在实现并发

单 worker 可以开 n 个进程进行工作,一个 worker 挂了往往所有进程都会挂掉

多 worker 假设为 m 个,可以理解为分布式,为了防止一个 worker 挂了(或者性能不足等原因),导致无法工作

那么能够并发处理的任务数量理论上为 m * n

一般 worker(不仅 celery,很多设计都是这样)指一个调度主进程 + 多个子工作进程

一个 worker 有什么缺点:

比较常见的是在不同机器部署多个 worker

在不考虑机器和进程挂掉但情况,其实一个 worker 开 8 个进程和 2 个 worker 每个开 4 个进程的效率是接近的

回答2:

celery 里面的-c 参数指定的是并发度,而-P 参数指定并发的实现方式,有 prefork (default)、eventlet、gevent 等,prefork 就是多进程的方式去实现并发。

你理解的多 worker 对应到多个进程,每个 worker (进程)自己内部还能并发是 gunicorn 的方式。gunicorn 的-w 参数指定有几个 worker (即几个进程),-k 参数指定每个 worker 的并发方式,可以是多线程或者多协程,也可以指定为 sync,表示 worker 是同步的,即不能并发。

比如 gunicorn 的-w 10 -k sync 和 celery 的-c 10 -P prefork 是等价的,都是创建 10 个进程去做并发,并发度最高就是 10。

再例如 celery 的-c 10 -P gevent 表示创建 10 个 gevent 协程去做并发,最高并发度也是 10。而 gunicorn 的-w 10 -k gevent,表示的是创建 10 个进程,且每个进程都是 gevent 异步的,这个并发度就很高了。

在 Python 中定义 Celery 的时候,我们要引入 Broker,中文翻译过来就是“中间人”的意思。在工头(生产者)提出任务的时候,把所有的任务放到 Broker 里面,在 Broker 的另外一头,一群码农(消费者)等着取出一个个任务准备着手做。这种模式注定了整个系统会是个开环系统,工头对于码农们把任务做的怎样是不知情的。所以我们要引入 Backend 来保存每次任务的结果。这个 Backend 也是存储任务的信息用的,只不过这里存的是那些任务的返回结果。我们可以选择只让错误执行的任务返回结果到 Backend,这样我们取回结果,便可以知道有多少任务执行失败了。

其实现架构如下图所示:

可以看到,Celery 主要包含以下几个模块:

celery可以通过pip自动安装。

broker 可选择使用RabbitMQ/redis,backend可选择使用RabbitMQ/redis/MongoDB。RabbitMQ/redis/mongoDB的安装请参考对应的官方文档。

------------------------------rabbitmq相关----------------------------------------------------------

官网安装方法: http://www.rabbitmq.com/install-windows.html

启动管理插件:sbin/rabbitmq-plugins enable rabbitmq_management 启动rabbitmq:sbin/rabbitmq-server -detached

rabbitmq已经启动,可以打开页面来看看 地址: http://localhost:15672/#/

用户名密码都是guest 。进入可以看到具体页面。 关于rabbitmq的配置,网上很多 自己去搜以下就ok了。

------------------------------rabbitmq相关--------------------------------------------------------

项目结构如下:

使用前,需要三个方面:celery配置,celery实例,需执行的任务函数,如下:

Celery 的配置比较多,可以在 官方配置文档: http://docs.celeryproject.org/en/latest/userguide/configuration.html 查询每个配置项的含义。

当然,要保证上述异步任务and下述定时任务都能正常执行,就需要先启动celery worker,启动命令行如下:

启动beat ,执行定时任务时, Celery会通过celery beat进程来完成。Celery beat会保持运行, 一旦到了某一定时任务需要执行时, Celery beat便将其加入到queue中. 不像worker进程, Celery beat只需要一个即可。而且为了避免有重复的任务被发送出去,所以Celery beat仅能有一个。

命令行启动:

如果你想将celery worker/beat要放到后台运行,推荐可以扔给supervisor。

supervisor.conf如下:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11559985.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存