概念:
Celery是一个高效的基于分布式消息传递的作业队列。它主要通过消息(messages)传递任务,通常使用一个叫Broker(中间人)来协调client(任务的发出者)和worker(任务的处理者)。clients发出消息到队列中,broker将队列中的信息派发给 Celery worker来处理。Celery本身不提供消息服务,它支持的消息服务(Broker)有RabbitMQ和Redis。小编一般推荐Redis,因为其在Django项目中还是首选的缓存后台。
1,要求
# pip安装必选 Django==3.2 celery==5.0.5 redis==3.5.3 # 可选,windows下运行celery 4以后版本,还需额外安装eventlet库 eventlet # 推荐安装, 需要设置定时或周期任务时安装,推荐安装 django-celery-beat==2.2.0 # 视情况需要,需要存储任务结果时安装,视情况需要 django-celery-results==2.0.1 # 视情况需要,需要监控celery运行任务状态时安装 folower==0.9.7
在正式使用celery
和django-celery-beat
之前,你需要做基础的配置。假如你的Django项目文件夹布局如下所示,你首先需要在myproject/myproject目录下新增celery.py
并修改__init__.py
。
基础配置
新建celery.py
,添加如下代码:
import os from celery import Celery # 设置环境变量 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') # 实例化 app = Celery('myproject') # namespace='CELERY'作用是允许你在Django配置文件中对Celery进行配置 # 但所有Celery配置项必须以CELERY开头,防止冲突 app.config_from_object('django.conf:settings', namespace='CELERY') # 自动从Django的已注册app中发现任务 app.autodiscover_tasks() # 一个测试任务 @app.task(bind=True) def debug_task(self): print(f'Request: {self.request!r}')
修改__init__.py
,如下所示:
from .celery import app as celery_app __all__ = ('celery_app',)
接下来修改Django项目的settings.py
,添加Celery有关配置选项,如下所示:
# 最重要的配置,设置消息broker,格式为:db://user:password@host:port/dbname # 如果redis安装在本机,使用localhost # 如果docker部署的redis,使用redis://redis:6379 CELERY_BROKER_URL = "redis://127.0.0.1:6379/0" # celery时区设置,建议与Django settings中TIME_ZONE同样时区,防止时差 # Django设置时区需同时设置USE_TZ=True和TIME_ZONE = 'Asia/Shanghai' CELERY_TIMEZONE = TIME_ZONE
其它Celery常用配置选项包括:
# 为django_celery_results存储Celery任务执行结果设置后台 # 格式为:db+scheme://user:password@host:port/dbname # 支持数据库django-db和缓存django-cache存储任务状态及结果 CELERY_RESULT_BACKEND = "django-db" # celery内容等消息的格式设置,默认json CELERY_ACCEPT_CONTENT = ['application/json', ] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' # 为任务设置超时时间,单位秒。超时即中止,执行下个任务。 CELERY_TASK_TIME_LIMIT = 5 # 为存储结果设置过期日期,默认1天过期。如果beat开启,Celery每天会自动清除。 # 设为0,存储结果永不过期 CELERY_RESULT_EXPIRES = xx # 任务限流 CELERY_TASK_ANNOTATIONS = {'tasks.add': {'rate_limit': '10/s'}} # Worker并发数量,一般默认CPU核数,可以不设置 CELERY_WORKER_CONCURRENCY = 2 # 每个worker执行了多少任务就会死掉,默认是无限的 CELERY_WORKER_MAX_TASKS_PER_CHILD = 200
完整配置选项见:
https://docs.celeryproject.org/en/stable/userguide/configuration.html#std-setting-result_expires
注意:
在Django中正式编写和执行自己的异步任务前,一定要先测试redis和celery是否安装好并配置成功。
一个无限期阻塞的任务会使得工作单元无法再做其他事情,建议给任务设置超时时间。
首先你要启动redis服务。windows进入redis所在目录(比如C:\redis),使用redis-server.exe
启动redis。Linux下使用./redis-server redis.conf
启动,也可修改redis.conf将daemonize设置为yes, 确保守护进程开启。
启动redis服务后,你要先进入项目所在文件夹运行python manage.py runserver
命令启动Django服务器(无需创建任何app),然后再打开一个终端terminal窗口输入celery命令,启动worker。
# Linux下测试,启动Celery Celery -A myproject worker -l info # Windows下测试,启动Celery Celery -A myproject worker -l info -P eventlet # 如果Windows下Celery不工作,输入如下命令 Celery -A myproject worker -l info --pool=solo
如果你能看到[tasks]下所列异步任务清单如debug_task
,以及最后一句celery@xxxx ready, 说明你的redis和celery都配置好了,可以开始正式工作了。
-------------- celery@DESKTOP-H3IHAKQ v4.4.2 (cliffs) --- ***** ----- -- ******* ---- Windows-10-10.0.18362-SP0 2020-04-24 22:02:38 - *** --- * --- - ** ---------- [config] - ** ---------- .> app: myproject:0x456d1f0 - ** ---------- .> transport: redis://127.0.0.1:6379/0 - ** ---------- .> results: redis://localhost:6379/0 - *** --- * --- .> concurrency: 4 (eventlet) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . myproject.celery.debug_task [2020-04-24 22:02:38,484: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0 [2020-04-24 22:02:38,500: INFO/MainProcess] mingle: searching for neighbors [2020-04-24 22:02:39,544: INFO/MainProcess] mingle: all alone [2020-04-24 22:02:39,572: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/0. [2020-04-24 22:02:39,578: WARNING/MainProcess] c:\users\missenka\pycharmprojects\django-static-html-generator\venv\lib\site-packages\celery\fixups\django.py:203: UserWarning: Using sett ings.DEBUG leads to a memory leak, never use this setting in production environments! leak, never use this setting in production environments!''') [2020-04-24 22:02:39,579: INFO/MainProcess] celery@DESKTOP-H3IHAKQ ready.
直接扣下来的代码,怕搞丢了
Django进阶:万字长文教你使用Celery执行异步和周期性任务(多图)
其中注意的点是CELERY导入的问题,有人说python 版本不对,但是这个调整有点麻烦,所有我换了一种方式,pip install importlib-metadata==4.8.3 安装了这个包就好了。
还有个问题就是测试运行的时候不能正常运行,小点就是需要到该项目文件下去运行cmd命令