软件环境
- fedora 33
- python 3.7.0
- celery 4.3.0
- redis 6.0.9
初识 celery
celery 是一个分布式队列任务处理系统,
她为我们提供了一系列的任务处理工具。
结识 celery 缘于企业(媒体行业)生产中的一个文章抓取需求:
把官方微信公众号上面不定期发布的文章同步到企业自己的信息库中。
当然,celery 不仅给我们提供了定时,还提供了定期处理任务的工具。
基于此背景,给出本文探究 celery 的一张导图:
在本文中,我们使用 redis 作为 celery 的 broker(打破隔阂的人),
broker 的作用为存储任务信息和支持诸如 celery events 等工具的任务监控功能。
案例代码
-
文件名: celery_test.py
import time from celery import Celery app = Celery( 'celery_test', # 应用名称(can omit ^_^) broker='redis://127.0.0.1:6379/3', backend='rpc://' # 不保存任务执行结果 ) # 任务对应的 broker 队列名称 app.conf.task_default_queue = 'queue_celery_test' @app.on_after_configure.connect def setup_periodic_tasks(sender, **kwargs): """注册任务 Args: sender (Celery): Celery application kwargs """ sender.add_periodic_task( 1, # 每隔 1s 注册一次任务 say_hi.s('hello celery'), # .s 表示函数签名 name='celery test', expires=5 # 注册任务 5s 后过期 ) @app.task def say_hi(args, **kwargs): """定义任务: 来自 celery 的问候 ^_^ Args: args (str) kwargs """ time.sleep(5) print(args) print(kwargs)
-
关于 celery worker
worker 是用来处理任务的具体执行人,
在本例中用命令venv/bin/python -m celery worker
来启动 worker。
命令中的venv/bin/python
解释器来自项目的 virtualenv 环境。可在多台机器上开启多个 worker 来处理 broker 队列中的任务。
启动 worker 后,任务的并发处理默认是由 python 的 multiprocessing 库实现的,
mutiprocessing 会启动默认数量为当前机器处理器核数(N)的进程。所以,一个 worker 每次会从 broker 队列中取出的任务数量不是 1,而是 N 。
可以在启动命令中用
-c
选项来控制 multiprocessing 启动的并发进程数,
比如说我们只想让一个进程专一地工作时,启动命令后面接-c 1
就可以了。 -
关于 celery beat
beat 就是用来定时或定期生产任务的,
产生的任务就由【说明2】中的 worker 来处理。如果在一个任务还没处理结束前又生产了一个相同的任务,就会造成任务叠加现象,
另外,borker 队列中可能会存在多个未处理的同类任务。所以,我们需要合理制定任务生产周期,以避免并发任务处理对业务数据的不可控影响。
也可以在启动 worker 命令中添加
--purge
选项,
这样会使worker 在每次获取 broker 队列中的任务之前清空队列。
因此,为每个 worker 设置特定的 broker 队列名称就显得尤为必要了。
如果不设置,就会清空其他不同业务 worker的任务队列数据。
使用命令总结
1. 启动 celery beat
```python -m celery -A proj_name beat -l info```
- 该命令代表启动 celery 的周期性任务调度程序,
- ```-m```代表以脚本方式运行 python 的某一模块库
- ```-A```代表我们编写的应用名称,在本代码示例中是 celery_test
- ```-l```代表运行过程中要输出的日志级别
2. 启动 celery worker
```python -m celery -A proj_name worker --purge -c 1 -l info```
- --purge 代表在获取任务前清空队列
- -c 代表并发处理数量,亦即系统为一个 worker 创建的进程数