APSscheduler
一、概述
1.1、介绍
APScheduler(Advanced Python Scheduler)是Python 轻量级定时任务框架,核心作用是帮你在 Python 程序中实现「定时执行代码」「循环执行代码」, 无需依赖 Linux crontab、Windows 任务计划程序等系统级定时工具,可直接嵌入 Django/Flask 等项目,是纯 Python 生态的定时任务解决方案。1.2、核心组件
# 四大核心组件
1、调度器(Scheduler):核心入口,管理所有任务的 “添加、删除、暂停、恢复、触发”,是使用 APScheduler 的唯一入口;
调度器类型
BlockingScheduler: 阻塞式,会阻塞主线程,适合独立脚本
BackgroundScheduler: 后台线程运行,不阻塞主线程,适合 Web 应用
AsyncIOScheduler: 适配 asyncio
GeventScheduler: 适配 gevent
TornadoScheduler: 适配 Tornado
TwistedScheduler: 适配 Twisted
QtScheduler: 适配 Qt 应用
2、触发器(Trigger):定时任务规则,定义任务 “何时执行”;
触发器类型
date: 一次性任务,指定日期时间执行
interval: 固定间隔执行
cron: 类似 Linux crontab 的时间表达式
3、任务(Job):你要定时运行的 Python 函数;
4、执行器(Executor):负责执行任务,支持线程池 / 进程池,控制 “同时执行多少个任务”。
默认使用线程池执行器
可配置进程池执行器
1.3、任务存储(Job Store)
决定任务配置的保存方式(是否重启后丢失)
| 存储类型 | 特点 | 适用场景 |
| ------------------ | ---------------------------- | --------------- |
| MemoryJobStore(默认) | 存在内存中,重启后丢失 | 测试 / 临时任务 |
| SQLAlchemyJobStore | 存在数据库,重启不丢 | 项目生产环境 |
| redis JobStore | 存在redis中,支持分布式 | 分布式项目可用
1.4、安装
# 最小化安装,这个会安装核心模块,99%功能覆盖,基本够用。
pip install apscheduler
# 完整安装
pip install apscheduler[all]
这会安装所有可选依赖,包括:
数据库后端支持
Redis 支持 # 用 RedisJobStore 存储任务
MongoDB 支持. # 用 MongoDBJobStore 存储任务
RethinkDB 支持
ZooKeeper 支持。
SQLAlchemy 支持
# 按需安装,你可以根据需求只安装需要的组件:
# 1. 如果你只需要使用数据库存储(推荐大多数情况)
pip install apscheduler[sqlalchemy]
# 2. 使用 Redis 作为作业存储
pip install apscheduler[redis]
# 3. 使用 MongoDB
pip install apscheduler[mongo]
# 4. 使用 etcd
pip install apscheduler[etcd]
# 5. 使用 ZooKeeper
pip install apscheduler[zookeeper]
# 6. 使用 RethinkDB
pip install apscheduler[rethinkdb]
# 7. 使用 Twisted(异步框架)
pip install apscheduler[twisted]
# 8. 使用 Tornado
pip install apscheduler[tornado]
# 9. 使用 asyncio
pip install apscheduler[asyncio]
# 10. 使用 gevent
pip install apscheduler[gevent]
# 11. 使用 Qt
pip install apscheduler[qt]
# 最小化安装,这个会安装核心模块,99%功能覆盖,基本够用。
pip install apscheduler
# 完整安装
pip install apscheduler[all]
这会安装所有可选依赖,包括:
数据库后端支持
Redis 支持 # 用 RedisJobStore 存储任务
MongoDB 支持. # 用 MongoDBJobStore 存储任务
RethinkDB 支持
ZooKeeper 支持。
SQLAlchemy 支持
# 按需安装,你可以根据需求只安装需要的组件:
# 1. 如果你只需要使用数据库存储(推荐大多数情况)
pip install apscheduler[sqlalchemy]
# 2. 使用 Redis 作为作业存储
pip install apscheduler[redis]
# 3. 使用 MongoDB
pip install apscheduler[mongo]
# 4. 使用 etcd
pip install apscheduler[etcd]
# 5. 使用 ZooKeeper
pip install apscheduler[zookeeper]
# 6. 使用 RethinkDB
pip install apscheduler[rethinkdb]
# 7. 使用 Twisted(异步框架)
pip install apscheduler[twisted]
# 8. 使用 Tornado
pip install apscheduler[tornado]
# 9. 使用 asyncio
pip install apscheduler[asyncio]
# 10. 使用 gevent
pip install apscheduler[gevent]
# 11. 使用 Qt
pip install apscheduler[qt]
二、使用
1.1、最小示例
先跑一个最简单的例子,直观感受 APScheduler 的用法:# 导入核心模块
from apscheduler.schedulers.blocking import BlockingScheduler
# 1. 定义要定时执行的任务(任意 Python 函数)
def say_hello():
print("Hello APScheduler! 当前时间:", __import__('datetime').datetime.now())
# 2. 创建调度器(BlockingScheduler:阻塞式,适合独立脚本)
scheduler = BlockingScheduler()
# 3. 添加任务:每 5 秒执行一次 say_hello 函数
scheduler.add_job(
func=say_hello, # 要执行的函数
trigger="interval", # 触发规则:固定间隔
seconds=5 # 间隔 5 秒
)
# 4. 启动调度器(程序会阻塞在这里,持续执行任务)
if __name__ == '__main__':
try:
scheduler.start()
except KeyboardInterrupt: # 按 Ctrl+C 停止
scheduler.shutdown()
运行效果:控制台每 5 秒打印一次 Hello APScheduler! 当前时间:xxxx。
1.2、三种触发器用法介绍
触发器是 APScheduler 的核心,决定任务的执行时间,支持 3 种核心类型,覆盖所有定时场景
1. date 触发器:一次性触发(指定具体时间)
适合 “某个固定时间点执行一次” 的场景(如 “2025 年 12 月 25 日 20:00 执行”)
eg:
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def task():
print("一次性任务执行!时间:", datetime.now())
scheduler = BlockingScheduler()
# 方式1:指定具体时间字符串(格式:YYYY-MM-DD HH:MM:SS)
scheduler.add_job(
task,
'date', # 触发器:固定时间点执行一次
run_date='2025-12-25 20:00:00', # 时间点
id='one_time_task' # 给任务起个名字
)
scheduler.start()
2、interval 触发器:固定间隔触发
适合 “每隔 N 秒 / 分 / 时 / 天执行” 的场景(如 “每 10 分钟检查一次任务状态”)
from apscheduler.schedulers.blocking import BlockingScheduler
def task():
print("间隔任务执行!时间:", __import__('datetime').datetime.now())
scheduler = BlockingScheduler()
# 添加任务:每 1 分钟执行一次(支持 seconds/minutes/hours/days/weeks)
scheduler.add_job(
task,
'interval',
minutes=1, # 间隔 1 分钟
# 可选:start_date/end_date 限制执行时间范围
# start_date='2025-12-20 08:00:00',
# end_date='2025-12-20 18:00:00',
id='interval_task'
)
scheduler.start()
# 常用参数:
seconds:秒(如 seconds=10 → 每 10 秒);
minutes:分钟(如 minutes=5 → 每 5 分钟);
hours:小时(如 hours=1 → 每小时);
days:天(如 days=1 → 每天);
weeks:周(如 weeks=1 → 每周)。
3、cron 触发器:crontab 表达式触发(最常用)
适合 “复杂时间规则”(如 “每天凌晨 2 点执行”“每周一三五 18:00 执行”),完全兼容 Linux crontab 表达式,是生产环境最常用的触发器。
from apscheduler.schedulers.blocking import BlockingScheduler
def task():
print("Cron 任务执行!时间:", __import__('datetime').datetime.now())
scheduler = BlockingScheduler()
# 示例1:每天凌晨2点执行
scheduler.add_job(task, 'cron', hour=2, minute=0, id='cron_task1')
# 示例2:每周一、三、五 18:00 执行
scheduler.add_job(task, 'cron', day_of_week='1,3,5', hour=18, minute=0, id='cron_task2')
# 示例3:每月1号 00:00 执行
scheduler.add_job(task, 'cron', day=1, hour=0, minute=0, id='cron_task3')
# 示例4:每15分钟执行一次(和 interval 等效,但更贴合 crontab 习惯)
scheduler.add_job(task, 'cron', minute='*/15', id='cron_task4')
# 示例5:直接传 crontab 字符串(分 时 日 月 周)
scheduler.add_job(task, 'cron', cron_expression='0 2 * * *', id='cron_task5')
scheduler.start()
三、任务管控
APScheduler 支持对任务进行全生命周期管控(增删改查 / 暂停恢复),核心方法如下(以上述示例的 scheduler 为例):
1. 添加任务(已讲)
核心:scheduler.add_job(func, trigger, **trigger_args, id='任务ID', replace_existing=True)
id:任务唯一标识(必填,用于后续管控);
replace_existing=True:如果任务 ID 已存在,替换原有任务(避免重复)。
2. 查询任务
# 查询单个任务(通过ID)
job = scheduler.get_job('cron_task1')
if job:
print("任务ID:", job.id)
print("任务状态:", job.status) # pending/running/paused/finished
print("下次执行时间:", job.next_run_time)
# 查询所有任务
jobs = scheduler.get_jobs()
for job in jobs:
print(f"任务 {job.id}:状态={job.status},下次执行={job.next_run_time}")
3、暂停任务
# 暂停单个任务(通过ID)
scheduler.pause_job('cron_task1')
# 暂停所有任务
scheduler.pause_all()
4、恢复任务
# 恢复单个任务
scheduler.resume_job('cron_task1')
# 恢复所有任务
scheduler.resume_all()
5、修改任务(动态调整触发规则)
# 将“每天凌晨2点”改为“每天凌晨3点”
scheduler.modify_job('cron_task1', hour=3)
# 也可通过 job 对象修改
job = scheduler.get_job('cron_task1')
job.modify(hour=3)
6、删除任务
# 删除单个任务(通过ID)
scheduler.remove_job('cron_task1')
# 删除所有任务
scheduler.remove_all_jobs()
7、立即执行任务(手动触发)
# 立即执行指定任务(不影响原有定时规则)
scheduler.run_job('cron_task1')
四、Django 集成
1. 初始化调度器(全局唯一)
在 Django 项目根目录创建 scheduler.py
# scheduler.py
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.django import DjangoJobStore # Django 数据库存储
from apscheduler.executors.pool import ThreadPoolExecutor
from django.conf import settings
# 初始化调度器(后台式,不阻塞Django)
def init_scheduler():
scheduler = BackgroundScheduler(timezone=settings.TIME_ZONE)
# 1. 添加Django数据库存储(任务持久化,重启不丢失)
scheduler.add_jobstore(DjangoJobStore(), 'default')
# 2. 配置执行器(线程池,控制并发数)
executors = {
'default': ThreadPoolExecutor(20) # 同时执行20个任务
}
scheduler.configure(executors=executors)
return scheduler
# 全局调度器实例(确保整个Django只有一个)
scheduler = init_scheduler()
2. Django 启动时加载调度器
修改 wsgi.py(或 asgi.py):
# wsgi.py
import os
from django.core.wsgi import get_wsgi_application
from .scheduler import scheduler
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的项目名.settings')
application = get_wsgi_application()
# 启动调度器(仅启动一次)
if not scheduler.running:
scheduler.start()
3. 迁移数据库(创建任务存储表)
python manage.py migrate
4、编写业务任务代码并使用scheduler即可
注意:给任务函数加完整的异常捕获,避免单个任务失败导致调度器崩溃
注意:APScheduler在嵌入django项目时,有个问题,django的uWSGI 等web服务器 一般都是多进程的,多个进程会启动多个scheduler调度器,会导致同一个定时任务被调度多次。需要自己解决这个问题(redis 分布式锁,或者专用进程启动调度器或者数据库锁等等),或者只使用单进程(单进程影响性能,小项目可以考虑)
web应用时可以考虑使用Celery

浙公网安备 33010602011771号