做视频网站需要什么条件,商城源码价格低 质量好,亚马逊网站风格,建筑人才网怎么和招聘人说话Celery是一个简单、灵活且可靠的分布式系统#xff0c;专门用于处理大量消息的实时任务调度。它支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度。Celery不仅支持异步任务#xff08;如发送邮件、文件上传、图像处理等耗时操作#xff09;#xff0c;还支持… Celery是一个简单、灵活且可靠的分布式系统专门用于处理大量消息的实时任务调度。它支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度。Celery不仅支持异步任务如发送邮件、文件上传、图像处理等耗时操作还支持定时任务即需要在特定时间执行的任务。Celery本身不提供消息服务需要借助RabbitMQ、Redis等消息中间件本案例使用的是Redis。 Celery Beat则是Celery的一个组件专门用于处理定时任务调度。它包含一个调度器负责根据配置的时间表计划任务的执行。这些任务通常是Celery任务即异步执行的函数或方法。Celery Beat将计划的任务发送到Celery任务队列由Celery Worker处理并执行队列中的任务。此外Celery Beat还支持任务的持久性即使在系统重启后也能够保持已计划的周期性任务。 开发环境Python3 MySQL Redis PyCharm专业版
一、创建Django项目
参考 Python框架Django入门教程-CSDN博客 前三步
二、安装celery、mysql、redis等依赖包
eventlet 是一个python协程模板celery 4版本以上在windows环境进行测试需要安装此依赖
django_celery_results 是任务执行结果的依赖
mysqlclient
redis
celery
eventlet
django-celery-beat
django_celery_results
三、初始化Celery数据库
打开PyCharm的终端执行以下命令
python manage.py makemigrations
python manage.py migrate
打开数据库查看执行命令后自动创建了一些表 django_celery_beat_clockedschedule # 以指定时间执行任务例如2024-05-22 09:22:10
django_celery_beat_crontabschedule # 以crontab格式时间执行任务某月某天星期几某时某分
django_celery_beat_intervalschedule # 以间隔时间执行任务例如每5秒、每2小时
django_celery_beat_periodictask # 存储要执行的任务。
django_celery_beat_periodictasks # 索引和跟踪任务更改状态
django_celery_beat_solarschedule # 以天文时间执行任务例如日出、日落
django_celery_results_chordcounter # 存储Celery的chord任务的状态
django_celery_results_groupresult # 存储Celery的group任务的结果
django_celery_results_taskresult # 存储Celery任务的执行结果
四、配置Celery
修改注意是修改不是添加settings.py找到 INSTALLED_APPS变量约31行将celery注册到django的应用管理中 在settings.py末尾添加celery配置
CELERY_BROKER_URL redis://localhost:6379/0 # 使用Redis作为消息代理
CELERY_RESULT_BACKEND redis://localhost:6379/0 # 结果存储也使用Redis
# 配置 celery 定时任务使用的调度器使用django_celery_beat插件用来动态配置任务
CELERY_BEAT_SCHEDULER django_celery_beat.schedulers:DatabaseScheduler
# 配置celery自动存储任务执行结果
CELERY_RESULT_BACKEND django_celery_results.backends:DatabaseBackend
CELERY_TIMEZONE Asia/Shanghai # 设置时区
# 是否启用UTC
CELERY_ENABLE_UTC False
# 是否开启时间感知
DJANGO_CELERY_BEAT_TZ_AWARE False
在settings.py同级目录下创建celery.py然后添加以下内容
import osfrom celery import Celery
from django.conf import settings# djangoDemo是项目名大家根据自己的情况进行替换
os.environ.setdefault(DJANGO_SETTINGS_MODULE, djangoDemo.settings)
# djangoDemo是项目名大家根据自己的情况进行替换
app Celery(djangoDemo)
# 从django的设置中读取配置信息
app.config_from_object(django.conf:settings, namespaceCELERY)
# 自动发现app下的任务
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)app.task(bindTrue)
def debug_task(self):print(fRequest: {self.request!r})
五、创建应用模块进行测试
打开PyCharm终端执行命令创建应用模块这里命名为celeryapp将新的应用模块注册到django的应用管理中
python manage.py startapp celeryapp 在新的应用模块中创建tasks.py添加异步函数文件名必须是tasks.py否则后面启动Celery的时候监听不到
shared_task
def task_one():print(------------------------- 000 )# 业务逻辑...print(------------------------- 111 )return 222
在新的应用模块中修改views.py添加一个测试接口。这里说一个坑在settings.py中配置了TIME_ZONE Asia/Shanghai 和 USE_TZ True 之后通过datetime.now()获取的是亚洲上海时间但是把这个时间存到数据库就会自动减少8小时变成了UTC时间就很无语于是我把USE_TZ的值改为False发现存到数据库中的时间变成正常的亚洲上海时间。然而Celery定时执行任务的时区是UTC经过多次测试配置了CELERY_TIMEZONE等时区相关的配置发现好像并没什么用Celery定时执行任务的时区依然是UTC无奈只能把任务执行的时间减少8小时
import json
from datetime import datetime, timedeltafrom django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django_celery_beat.models import ClockedSchedule, PeriodicTaskdef celery_test(request):# 任务名task_name celery_test# 任务执行的时间设置为下一分钟的10秒celery执行时间的时区是UTC要保证数据库中的时间是UTC时间这里获取的是亚洲上海的时间所以减了8小时time (datetime.now() - timedelta(hours8) timedelta(minutes1)).strftime(%Y-%m-%d %H:%M:10)# 创建任务的执行时间clock ClockedSchedule.objects.get_or_create(clocked_timetime)# 创建指定时间执行的celery任务PeriodicTask.objects.update_or_create(nametask_name, # 任务名尽量保证唯一性若该任务已存在则更新该任务taskceleryapp.tasks.task_one, # 要执行的异步函数的全路径defaults{clocked: clock[0], # 使用clocked在指定时间执行该任务one_off: True, # 在任务执行完一次后关闭该任务enabled: True, # 开启任务args: json.dumps([]), # 参数列表必须是json格式的数组})return JsonResponse({message: 200})
修改urls.py在urlpatterns中添加路由
from celeryapp import viewsurlpatterns [# ......path(celery/test/, views.celery_test),
]六、启动项目进行测试
先启动Django项目然后在分别两个终端中执行命令启动Celery和Celery Beat命令中的djangoDemo是项目名大家根据自己的情况进行替换
celery -A djangoDemo worker -P eventlet -l info # 启动worker监听异步任务
celery -A djangoDemo beat -l info # 启动beat任务调度器
这里的woker已经监听到我们创建的celeryapp.tasks.task_one异步函数了 这里说明beat启动成功了 浏览器输入请求地址http://127.0.0.1:8000/celery/test/ 创建Celery任务
接口请求成功后查看数据库django_celery_beat_periodictask表新增了一条异步任务其中的clocked_id字段指向django_celery_beat_clockedschedule表该表新增了一条任务的执行时间。celery.backend_cleanup是Celery自动创建的不用管 在到达任务执行时间后观察woker和beat的终端日志
查看beat终端日志红框第一行是我们发送请求成功创建异步任务之后CeleryBeat已经检测到数据库中有任务发生变化CeleryBeat每5秒检测一次使用debug级日志可查看到第二行CeleryBeat将一个名为celery_test的任务发送给worker让woker执行celeryapp.tasks.task_one异步函数消费该任务 在woker终端的日志中可以看到任务执行的结果 七、 Celery Beat常用的三种时间控制器
clockedSchedule指定某个时间执行任务例如2024-05-22 09:22:10对应的表是django_celery_beat_clockedschedule该表仅有id和clocked_time两个字段
crontabSchedule指定crontab格式的时间执行任务某月某天星期几某时某分与linux的定时任务规则一致可参考Linux定时任务-CSDN博客对应的表是django_celery_beat_crontabschedule该表有7个字段 id minute 分钟hour 小时day_of_week 星期几day_of_month 每月的哪些天month_of_year 每年的哪些月份timezone 时区
intervalSchedule间隔指定时间执行任务对应的表是django_celery_beat_intervalschedule该表有3个字段id、every间隔时长、period时间单位可选时、分、秒、微秒、天
代码示例clockedSchedule上面已经演示过了这里只演示另外两种
# crontabSchedule
def celery_test2(request):task_name celery_test2crontab CrontabSchedule.objects.get_or_create(minute*/1, # 每1分钟hour*, # 每小时day_of_week*, # 一周中的哪几天*表示每天day_of_month*, # 月份中的哪一天*表示每一天month_of_year*, # 年中的哪一月*表示每个月timezoneAsia/Shanghai)PeriodicTask.objects.update_or_create(nametask_name,taskceleryapp.tasks.task_one, # Celery任务的全路径defaults{crontab: crontab[0], # 使用crontab格式时间执行该任务one_off: False, # 在任务执行完一次后关闭该任务enabled: True, # 开启任务args: json.dumps([]),})return JsonResponse({message: 200})# intervalSchedule
def celery_test3(request):task_name celery_test3interval IntervalSchedule.objects.get_or_create(every1, # 间隔时间periodIntervalSchedule.MINUTES, # 周期单位这里是分钟)PeriodicTask.objects.update_or_create(nametask_name,taskceleryapp.tasks.task_one, # Celery任务的全路径defaults{interval: interval[0], # 使用interval间隔指定时间执行该任务one_off: False, # 在任务执行完一次后关闭该任务enabled: True, # 开启任务args: json.dumps([]),})return JsonResponse({message: 200})
其实只要创建不同的时间控制器然后在创建任务的时候作为参数放进去即可注意一个任务只能使用一种时间控制器 参考文献
https://blog.csdn.net/wuwei_201/article/details/129650089
https://blog.51cto.com/u_15703497/6252757