Python-Celery定时任务、延时任务、周期任务、crontab表达式及清除任务的基本使用与踩坑

Celery定时任务/延时任务

前面已经学习了Celery实现异步任务的提交,但是Celery也可以实现定时的任务,对于后端项目中,我们往往需要定时的清除/更新/备份一些相关内容,就可以通过celery进行执行。

1. 定时任务

Celery中自带有的apply_async方法,可以通过传入eta参数,实现定时任务的执行。

from celery_demo.sms_tasks import send_sms
# 导入已经使用装饰器装饰过的事件函数
from datetime import datetime
# 导入datetime日期时间对象

time_loc = datetime(2023,8,15,17,59,59)
# 定义datetime对象,设置时间为2023/8/15 17:59:59
# 这里的时间是计算机本地时间,也就是北京时间
# celery需要转换utc时间

time_utc = datetime.utcfromtimestamp(time_loc.timestamp())
# 转换utc时间对象
task = send_sms.apply_async(args=('小李',), eta=time_utc)
# apply_async 方法传入eta参数定时执行任务

print(task.id)
# 打印事件id,用于后续获取执行结果

apply_async方法如果不带eta参数,那其实和delay方法是一样的,仅仅就多了一个eta参数

2. 延时任务

Celery并没有直接设置的延时任务

需要我们自定义一个datetime对象进行延时任务的设置

from celery_demo.sms_tasks import send_sms
from datetime import datetime,timedelta
# timedelta模块用于设置时间差

now_time = datetime.utcnow()
# 获取当前的utc时间对象
timing = now_time + timedelta(seconds=10)
# 延时10分钟后,其他参数days/seconds/microseconds/...可以设置天/秒/微秒延时
task = send_sms.apply_async(args=('小李',), eta=now_time)
# 传入时间对象

print(task.id)
# 打印事件id,用于后续获取执行结果

3. 周期性定时任务

celery封装了beat_schedule,周期性任务,我们可以通过定义celery.conf.beat_schedule配置,进行周期性任务的设置,配置完成后,通过命令启动beat 进程,即可进行周期性定时任务。

3.1 周期性定时任务定义

from datetime import timedelta
from celery.schedules import crontab # 导入crontab表达式函数
from celery import Celery

cel = Celery('CeleryDemo',
             broker='redis://192.168.32.128:6379/0',
             backend='redis://192.168.32.128:6379/1',
             include=[
                 'celery_demo.sms_tasks',
                 'celery_demo.wechat_tasks'
             ])


cel.conf.beat_schedule = {
    # 这里的名字可以随便取,是对定时任务的命名
    # 但是里面的参数,不可以更改!
    "xxx名字随便定义": {
        "task": "celery_demo.sms_tasks.send_sms",
        "schedule": timedelta(seconds=6), # 定时6秒执行一次
        # "schedule": 10.0, # 每10秒执行一次 
        # "schedule": crontab(minute='*/1'), # 定时每分钟执行一次
        # 使用的是crontab表达式
        "args": ('李四',) # 函数传参的值
    }
}

3.2 使用命令启动beat任务

celery -A myapp beat --loglevel=info

此时,我们可以看到,任务已经在以6秒一次去循环提交

在这里插入图片描述

3.3 crontab表达式

crontab表达式是非常成熟但是复杂的表达式,它可以控制实现周期性任务,例如每周/每天/几点/偶数时间/周几…等各类复杂时间表达式定时。

3.3.1 crontab参数详解

crontab 函数的所有参数及其解释如下:

  • minute:分钟,取值范围为0-59或者*表示匹配所有分钟。
  • hour:小时,取值范围为0-23或者*表示匹配所有小时。
  • day_of_week:星期几,取值范围为0-6(0表示周一,6表示周日)或者*表示匹配所有星期几。
  • day_of_month:月份中的日期,取值范围为1-31或者*表示匹配所有日期。
  • month_of_year:年份中的月份,取值范围为1-12或者*表示匹配所有月份。
  • timezone:时区,可以使用pytz.timezone函数来指定时区,默认为None表示使用UTC时区。

3.3.2 使用案例

  1. 每分钟执行一次:
schedule = crontab(minute='*/1')
  1. 每小时的第30分钟执行一次:
schedule = crontab(minute=30)
  1. 每天的午夜执行一次:
schedule = crontab(minute=0, hour=0)
  1. 每周一的上午10点执行一次:
schedule = crontab(minute=0, hour=10, day_of_week=1)
  1. 每个月的第一天午夜执行一次:
schedule = crontab(minute=0, hour=0, day_of_month=1)
  1. 每隔5分钟执行一次,但只在周一和周二执行:
schedule = crontab(minute='*/5', day_of_week='mon,tue')
  1. 每小时执行一次,但排除周末(周六和周日):
schedule = crontab(minute=0, hour='*/1', day_of_week='mon-fri')
  1. 每天的上午9点至下午5点,每隔30分钟执行一次:
schedule = crontab(minute='*/30', hour='9-17')
  1. 每月的1号和15号,上午10点和下午4点执行一次:
schedule = crontab(minute=0, hour='10,16', day_of_month='1,15')

3.3.3 更改时区

如果需要按照本地中国时间,进行定时任务的执行,则需要使用timezone,默认使用的是utc时间

from celery.schedules import crontab
from pytz import timezone # 导入timezone


crontab(hour=22, minute=0, tz=timezone('Asia/Shanghai'))
# 定义上海(=北京)时间,每天晚上10点整执行。

4. 周期性任务踩坑

首先,周期性任务,是一个开启后就会不断提交的任务。

这里我们要看清楚最重要的两个字:提交

也就是说,周期性任务beat开启后,并不是直接执行,而是重复的提交到队列中

我们现在使用

celery -A myapp beat --loglevel=info

将周期性提交任务启动,此时只是任务被提交到队列,但是并不会执行,因为并没有开启worker

在这里插入图片描述

通过Redis,我们可以看到celery-list中的数据,在不断的增加,此时会大量的积压任务,当我们开启beat进程后,就会瞬间释放任务,将其全部执行。

在这里插入图片描述

此时Redis中队列长度变为0,已经全部执行结束

在这里插入图片描述

4.1 清除所有积压任务

但是,在实际的生产过程中,对于已经积压的任务,我们往往都是希望去删除掉,而不是给他全部都执行了,如果希望在执行新的beat任务之前,清除所有的积压任务,可以使用 purge 参数,清除所有队列任务

celery -A celery实例名/包 purge

eg:
	celery -A celery_demo.main purge # 清除celery_demo.main中实例的所有积压任务

在这里插入图片描述

可以发现,已经清除完成!
,清除所有的积压任务,可以使用 purge 参数,清除所有队列任务**

celery -A celery实例名/包 purge

eg:
	celery -A celery_demo.main purge # 清除celery_demo.main中实例的所有积压任务

在这里插入图片描述

可以发现,已经清除完成!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用 Celery 实现定时任务的示例: 1. 首先安装 celery: ``` pip install celery ``` 2. 在项目的根目录下新建一个名为 tasks.py 的文件,编写定时任务的代码: ``` from celery import Celery app = Celery('tasks', broker='redis://localhost:6379/0') @app.task def task1(): # 在这里编写 task1 的逻辑 pass @app.task def task2(): # 在这里编写 task2 的逻辑 pass ``` 其中,broker 参数指定 celery 使用 redis 存储任务队列和结果的地址,需要根据实际情况修改。这里演示了两个定时任务,分别是 task1 和 task2。 3. 在项目的根目录下新建一个名为 celery.py 的文件,配置 celery: ``` from celery import Celery from celery.schedules import crontab app = Celery('tasks', broker='redis://localhost:6379/0') app.conf.beat_schedule = { 'task1': { 'task': 'tasks.task1', 'schedule': crontab(minute='*/5'), # 每5分钟执行一次 }, 'task2': { 'task': 'tasks.task2', 'schedule': crontab(hour=1, minute=0), # 每天凌晨1点执行 }, } ``` 其中,beat_schedule 参数是定时任务的配置,具体格式可以参考 Celery 文档。这里演示了两个定时任务,分别是每5分钟执行一次的 task1 和每天凌晨1点执行的 task2。 4. 启动 celery: ``` celery -A celery worker -l info -B ``` 其中,-A 参数指定 celery 的应用名,-l 参数指定日志级别,-B 参数表示启动 celery 定时任务。 至此,就完成了 Celery定时任务配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值