前言
前段时间,工作中有个要求,是将本来的定时工作,改成应用celery实现。本来我的项目中的定时工作是应用的apscheduler。然而django与celery做定时的教程,网上比拟少,且版本对应不上,最初依据网上的教程+仔仔细细看了好多遍celery官网文档,终于跑通。
当初做一个疾速实现django+celery定时工作的教程/记录。
对于这三个组件的基础知识及装置就不赘述了。间接进入配置。
版本
Django==3.1.4
celery==5.0.5
redis==3.5.3
思路步骤
配置celery定时工作的思路和步骤次要为
- 创立celery实例
- 配置工作
- 编写工作函数
- 启动woker和beat
- 存储后果
目录层级(供参考)
django_demo # 我的项目根目录 ├── scheduler # 这是一个app │ ├── __init__.py │ ├── celery.py # 实例化celery并指定config │ ├── config.py # celery的配置文件 │ └── tasks.py # 工作函数
celery.py
from __future__ import absolute_importfrom celery import Celeryapp = Celery("scheduler", broker="redis://:12345@localhost:6379/1", backend="redis://:12345@localhost:6379/2", include=["scheduler.tasks"])app.config_from_object("scheduler.config")
此文件用于实例化celery,并指定broker和backend为redis(可写入配置文件)
include是指向task文件
app.config_from_object()指定celery的配置
config.py
from __future__ import absolute_importfrom datetime import timedeltaCELERY_TIMEZONE = "Asia/Shanghai"CELERY_ENABLE_UTC = TrueCELERYBEAT_SCHEDULE = { "test": { #工作名,用于开发人员辨认 "task": "scheduler.tasks.test", #task指向工作函数 "schedule": timedelta(seconds=2), #调度工夫 还能够应用crontab "args": () #没有参数能够不写 },}
此文件能够写一些celery的配置,以及通过CELERYBEAT_SCHEDULE将定时工作加载。
定时的工夫能够应用crontab。
例如:crontab(hour="*/24") 示意每24小时执行一次
也能够指定工夫,详情参照crontab的应用办法
tasks.py
from scheduler.celery import app@app.task()def test(): print("hello") return None
import app肯定是从实例化的celery.py中导入的。如果实例化文件不叫celery.py,或者对象不叫app,须要对应扭转。
工作函数须要应用@app.task()进行装璜。如果无需返回值,能够不写return。
终端命令启动worker及beat
此处须要开2个终端,或者在liunx中一起写入shell脚本中均可
celery -A scheduler.celery beat -l info # 启动beatcelery -A scheduler.celery worker -l info
scheduler.celery 是依据目录及文件所定的,请依据本人的我的项目进行扭转
-l info : 运行时输入日志
如果是在windows下进行启动则worker命令须要替换为
-P eventlet :是windows下启动worker, 其余零碎删除
(如果提醒eventlet没有就应用pip装置下eventlet)
celery -A scheduler.celery worker -l info -P eventlet # windows下启动worker
以上是对于celery定时工作的简略配置
在工作我的项目中,代码须要尽可能的简洁,配置须要放在同一个总的配置文件中,并且我的项目分为开发和线上环境,所以最初我的django配置是这样的:
django_demo # 我的项目根目录 ├── settings | ├── base.py #根底设置 | ├── develop.py #开发环境设置 ├── scheduler # 这是一个app │ ├── __init__.py │ ├── celery.py # 实例化celery并指定config │ └── tasks.py # 工作函数
我将上方的config.py中的配置别离写进了django中的settings文件中。
1. settings:
- develop.py:
BROKER_URL = redis_urlCELERY_RESULT_BACKEND = redis_url
开发环境下,配置开发所用的broker 和 backend,留神变量名不能写错,否则celery辨认不出
redis_url是咱们的redis端口,我这里是写在了其余中央,不便对所有的组件进行治理。
也能够这样写:
BROKER_URL = "redis://:12345@localhost:6379/1"CELERY_RESULT_BACKEND = "redis://:12345@localhost:6379/1"
base.py:
此处我将工作的调度写入了我的项目的base配置。# celery配置及工作配置CELERY_TIMEZONE = "Asia/Shanghai"CELERY_ENABLE_UTC = TrueCELERYBEAT_SCHEDULE = { "job1": { "task": "scheduler.tasks.job1", "schedule": crontab(minute=0, hour=3), }, "job2": { "task": "scheduler.tasks.job2", "schedule": crontab(hour="*/24"), },}
2. celery.py
from __future__ import absolute_importimport osfrom celery import Celeryprofile = os.environ.setdefault("PROFILE", "production")os.environ.setdefault("DJANGO_SETTINGS_MODULE", f"demo.settings.{profile}")app = Celery("scheduler", include=["scheduler.jobs"])app.config_from_object("django.conf:settings")
- 这里为了不便开发与线上进行区别,首先进行了整体环境的设置。
- profile 以及 os.environ.setdefault 都是对我的项目环境进行的设置.
- celery的主体还是app与app.config_from_object.
能够发现,我这里的Celery()中的变量少了,更简洁了,这是因为,我把这些元素都写入了django的settings中了,celery实例化的时候,会依据我配置的"django.conf:settings"进行查找对应的值。
3.jobs.py
from scheduler.celery import app@app.task()def job1(): passdef job2(): pass
总结:
celery实现定时工作还是比拟容易实现的。次要是celery的实例化,配置与工作配置,工作函数,三个局部组成。对于配置能够随机应变,写到任何中央都能够。要害是三个文件在援用的时候,不必弄混就行了。
一个是实例化celery的时候,app.config_from_object() 留神写对咱们的配置门路
一个是配置文件中的配置定时工作时的工作函数门路
一个是工作函数的装璜器@app.task()肯定是实例化celery中的对象。
展现下定时工作正在执行的输入。
local是启动的worker
local2是启动的beat
beat终端中,运行起来的时候,会始终打印发送工作胜利。
worker会始终输入工作接管胜利,并返回return值及工作函数中的输入。
参考
- celery官网文档
- win10下实现django+celery定时工作 保姆级别教程