1. 安装所需包
pip install SQLAlchemy
pip install flask_apscheduler
2. 定义定时任务配置类
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from schedules.task import task1, task2
# 任务配置类
class SchedulerConfig(object):
# 配置执行job
JOBS = [
{
'id': 'put_into_queue',
'func': task1,
'args': None,
'trigger': 'interval',
'seconds': 60 * 3 # 本任务为每3分钟执行一次
},
{
'id': 'scheduler_dev_queueing',
'func': task2,
'args': None,
'trigger':{ # 本任务为每周一五点五十九分四十秒执行一次
'type': 'cron', # 类型
'day_of_week': "0", # 可定义具体哪几天要执行
'hour': '5', # 小时数
'minute': '59',
'second': '40' # "*/3" 表示每3秒执行一次,单独一个"3" 表示每分钟的3秒。现在就是每一分钟的第3秒时循环执行。
}
}
]
# 存储位置
SCHEDULER_JOBSTORES = {
'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
# 线程池配置
SCHEDULER_EXECUTORS = {
'default': {'type': 'threadpool', 'max_workers': 20}
}
# 配置时区
SCHEDULER_TIMEZONE = 'Asia/Shanghai'
SCHEDULER_JOB_DEFAULTS = {
'coalesce': False,
'max_instances': 3
}
# 调度器开关
SCHEDULER_API_ENABLED = True
3. 启动时加载定时任务
if __name__ == '__main__':
# 定时任务
app.config.from_object(SchedulerConfig())
# 同时指定时区,防止上下时区不一致
scheduler = APScheduler(BackgroundScheduler(timezone="Asia/Shanghai"))
# 注册app
scheduler.init_app(app)
scheduler.start()
app.run(host="0.0.0.0", port=5001, use_reloader=False)
4. 定时任务中配置
1. cron定时调度
- year (int|str) – 4位数年份
- month (int|str) – 月(1-12)
- day (int|str) – 日(1-31)
- week (int|str) – ISO week (1-53)
- day_of_week (int|str) – 工作日的编号或名称(0-6或周一、周二、周三、周四、周五、周六、周日)使用名称可能会报错,建议使用数字
- hour (int|str) – hour (0-23)
- minute (int|str) – minute (0-59)
- second (int|str) – second (0-59)
- start_date (datetime|str) – 最早可能触发的日期/时间(包括)
- end_date (datetime|str) – 最晚可能触发的日期/时间(包括)
- timezone (datetime.tzinfo|str) – 用于日期/时间计算的时区(默认为计划程序时区)
2. interval间隔调度
- weeks (int) – number of weeks to wait
- days (int) – number of days to wait
- hours (int) – number of hours to wait
- minutes (int) – number of minutes to wait
- seconds (int) – number of seconds to wait
- start_date (datetime|str) – 间隔计算的起点
- end_date (datetime|str) – 最晚可能触发的日期/时间
- timezone (datetime.tzinfo|str) – 用于日期/时间计算的时区
3. date定时调度
最基本的一种调度,作业只会执行一次。它的参数如下:
- run_date (datetime|str) – the date/time to run the job at
- timezone (datetime.tzinfo|str) – time zone for run_date if it doesn’t have one already
5. 注意事项
- 根据任务实际场景选择合适的定时任务执行方式
- 启动时最好设置
use_reloader=False
,这样就取消了重新加载机制,防止定时任务重复执行. - 本示例中使用sqlite3,需要的童鞋还可以使用mysql作为定时任务存储库
- 定时任务出现was missed by 0:00:04.387763解决办法:
1. 出现问题原因: 当时定时任务由于某些原因在当时错过了几秒钟才执行该任务,但是它认为已经过去了那个执行时间,所以调度失败
2. 在SCHEDULER_JOB_DEFAULTS中添加’misfire_grace_time’: 300
3. misfire_grace_time是进行调度可容忍时间,比如在自定义时间60s后才执行调度,那么我们设置的时间为300,该任务会重新调度.