简介
一般来说 Celery
是python可以执行定时任务, 但是不支持动态添加定时任务 (Django有插件可以动态添加), 而且对于不需要 Celery
的项目, 就会让项目变得过重.
APScheduler
支持持久化, 且可以动态添加定时任务.
$pip install apscheduler
APScheduler的各个组件的关系, 如下图:
一般使用
步骤:
-
创建调度器
-
配置调度器
- 任务存储器
- 执行器
- 全局配置
-
添加任务
-
运行调度任务
-
修改/删除任务
除此之外, 可以监听事件, 执行自定义的函数
import datetime from pytz import timezone from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.executors.pool import ProcessPoolExecutor from apscheduler.jobstores.memory import MemoryJobStore job_stores = { 'default': MemoryJobStore() } executors = { 'processpool': ProcessPoolExecutor(max_workers=5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } def hello_world(): print("hello world") # 阻塞调度器 scheduler = BlockingScheduler() scheduler.configure(jobstores=job_stores, executors=executors, job_defaults=job_defaults) # 在当前时间的3秒后, 触发执行hello_world, 详情见: "触发器与调度器API" scheduler.add_job(hello_world, "date", run_date=datetime.datetime.now() + datetime.timedelta(seconds=3), timezone=timezone("Asia/Shanghai")) scheduler.start()
调度器
配置作业存储器和执行器可以在调度器中完成。例如添加、修改、移除作业,根据不同的应用场景,可以选择不同的调度器,可选择的调度器如下:
# 阻塞式调度器 [ 调度器是你程序中唯一要运行的东西 ] from apscheduler.schedulers.blocking import BlockingScheduler # 后台调度器 [ 应用程序后台静默运行 ] from apscheduler.schedulers.background import BackgroundScheduler # AsyncIO调度器 [ 如果你的程序使用了 asyncio 库 ] from apscheduler.schedulers.asyncio import AsyncIOScheduler # Gevent调度器 [ 如果你的程序使用了 gevent 库 ] from apscheduler.schedulers.gevent import GeventScheduler # Tornado调度器 [ 如果你打算构建一个 Tornado 程序 ] from apscheduler.schedulers.tornado import TornadoScheduler # Twisted调度器 [ 如果你打算构建一个 Twisted 程序 ] from apscheduler.schedulers.twisted import TwistedScheduler # Qt调度器 [ 如果你打算构建一个 Qt 程序 ] from apscheduler.schedulers.qt import QtScheduler
在使用非阻塞的调度器时需要注意: 程序是否会退出从而无法执行任务
配置
有3种方式配置
方式一
from pytz import utc from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.jobstores.mongodb import MongoDBJobStore from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor # 键为名称 # 值为字典 实例化对象作为值, 参数直接在实例化时传入 jobstores = { 'mongo': MongoDBJobStore(), 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } executors = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
方式二
from pytz import utc from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ProcessPoolExecutor # 键为名称,值要为字典,type指定调度器, 其它键值对指定参数 jobstores = { 'mongo': {'type': 'mongodb'}, 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } executors = { 'default': {'type': 'threadpool', 'max_workers': 20}, 'processpool': ProcessPoolExecutor(max_workers=5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } scheduler = BackgroundScheduler() scheduler.configure(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
方式三
from apscheduler.schedulers.background import BackgroundScheduler # 前缀 "apscheduler." 是硬编码的 # apscheduler.jobstores指定任务存储器 # apscheduler.executors指定执行器 # 最后的 "." 指定名称 scheduler = BackgroundScheduler({ 'apscheduler.jobstores.mongo': { 'type': 'mongodb' }, 'apscheduler.jobstores.default': { 'type': 'sqlalchemy', 'url': 'sqlite:///jobs.sqlite' }, 'apscheduler.executors.default': { 'class': 'apscheduler.executors.pool:ThreadPoolExecutor', 'max_workers': '20' }, 'apscheduler.executors.processpool': { 'type': 'processpool', 'max_workers': '5' }, 'apscheduler.job_defaults.coalesce': 'false', 'apscheduler.job_defaults.max_instances': '3', 'apscheduler.timezone': 'UTC', })