django-crontab 最简单,类似crontab的方法进行定时任务的设置,但不支持Windows平台。
django-celery 非常晚上的定时任务库,但通常需要结合redis、es等中间件结合使用,重。
django-apscheduler 能够跨平台,能够设置多种定时任务,轻量级首选。
django-apscheduler
基于apscheduler库,为django定制的第三方库。
固定时间间隔
固定时间点(日期)
Crontab
调度器(scheduler) 任务调度器,属于控制器角色。它配置作业存储器和执行器可以在调度器中完成,例如添加、修改和移除作业。
作业存储(job store) 任务持久化仓库,默认保存任务在内存中,也可将任务保存都各种数据库中。
触发器(trigger) 描述调度任务被触发的条件。不过触发器完全是无状态的。
执行器(executor) 负责处理作业的运行,它们通常通过在作业中提交指定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。
共有七种调度器:
BlockingScheduler : 调度器在当前进程的主线程中运行,也就是会阻塞当前线程。
BackgroundScheduler : 调度器在后台线程中运行,不会阻塞当前线程。(Django框架使用)
AsyncIOScheduler : 结合 asyncio 模块(一个异步框架)一起使用。
GeventScheduler : 程序中使用 gevent(高性能的Python并发框架)作为IO模型,和 GeventExecutor
配合使用。
TornadoScheduler : 程序中使用 Tornado(一个web框架)的IO模型,用 ioloop.add_timeout
完成定时唤醒。
TwistedScheduler : 配合 TwistedExecutor,用 reactor.callLater
完成定时唤醒。scrapy爬虫框架
QtScheduler : 你的应用是一个 Qt 应用,需使用QTimer完成定时唤醒。
添加任务:
add_job() 该方法返回一个job实例,后期可通过其它方法对该定时任务进行修改。
@register_job() 使用装饰器的方法,一旦启动,在运行中无法进行变更。
删除任务:
scheduler.remove_job(job_name)
暂停任务:
scheduler.pause_job(job_name)
恢复任务:
scheduler.resume_job(job_name)
获取任务:
scheduler.get_jobs()
修改任务(仅能修改执行参数)
scheduler.modify_job(job_name)
重设任务(修改执行计划、参数等)
scheduler.reschedule_job(job_name)
scheduler.reschedule_job(job_id="job1", trigger='interval', minutes=1)
定时任务
# 装饰器类型
@register_job(Scheduler, 'date', run_date='2023-01-29 16:00:00:00', id='job_name')
def job_name():
pass
# add_job()
def job_name(args):
pass
Scheduler.add_job(job_name, 'date', run_date='2023-01-29 16:00:00:00')
间隔任务
# 装饰器类型
@register_job(scheduler, 'interval', minutes=5, id='job_name') # 5分钟执行一次
def job_name():
pass
# add_job()
def job_name(args):
pass
Scheduler.add_job(job_name, 'interval', seconds=60, args=['xx'])
crontab任务
# 装饰器类型
@register_job(scheduler, 'cron', hour='0,6', id='job_name') # 每天0,6点执行
def job_name():
pass
# add_job()
def job_name(args):
pass
Scheduler.add_job(job_name, 'cron', hour='0-3', seconds=60, args=['xx']) # 每天0点到3点,每隔60秒执行一次
1、安装
pip3 install django-apscheduler
2、settings.py注册
INSTALLED_APPS = [
......
'django_apscheduler',
]
3、数据迁移
python manage.py migrate
自动生成django_apscheduler_djangojob
和django_apscheduler_djangojobexecution
两张表
django_apscheduler_djangojob用于存储任务;
django_apscheduler_djangojobexecution用于存储任务执行状态。
4、实例化定时任务并自定义执行内容
# 实例化定时任务,以异步线程执行
scheduler = BackgroundScheduler()
# 使用DjangoJobStore进行调度
scheduler.add_jobstore(DjangoJobStore(), 'default')
@register_job(scheduler, 'interval', minutes=5, id='refresh')
def refresh():
pass
5、定时任务启动
scheduler.start()
django + uwsgi进行多进程启动时,定时任务多次执行问题。
答:使用fnctl
标准库(Windows下没有,默认会报错)实现文件锁,以此来规定只有一个进程执行定时任务。
def initscheduler(scheduler):
f = open("scheduler.lock", "wb")
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
logger.info('未获取到文件锁,开始加锁,执行scheduler定时任务。')
scheduler.start()
except:
pass
logger.info('文件加锁失败,scheduler已创建,跳过文件锁。')
def unlock():
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
atexit.register(unlock)
......省略具体执行内容......
# 尝试获取文件锁,以避免多次执行
initscheduler(scheduler)