跳转至

定时任务

推荐方案:FastScheduler

使用 fastscheduler,自带 FastAPI 控制面板,支持 cron 表达式、重试、持久化等。

安装

# 基础 + FastAPI面板 + cron支持
pip install fastscheduler[all]

与 FastAPI 集成

from fastapi import FastAPI
from fastscheduler import FastScheduler
from fastscheduler.fastapi_integration import create_scheduler_routes

app = FastAPI()
scheduler = FastScheduler(quiet=True)

# 挂载控制面板到 /scheduler/
app.include_router(create_scheduler_routes(scheduler))

@scheduler.every(30).seconds
async def background_task():
    print("Background work")

@scheduler.daily.at("02:00")
async def nightly_cleanup():
    await clean_old_sessions(days=10)

scheduler.start()

访问 http://localhost:8000/scheduler/ 查看控制面板(实时状态、暂停/恢复、执行历史、失败队列)。

常用调度方式

# 间隔调度
@scheduler.every(10).seconds
@scheduler.every(5).minutes
@scheduler.every(2).hours

# 定时调度
@scheduler.daily.at("09:00")
@scheduler.hourly.at(":30")
@scheduler.weekly.monday.at("10:00")
@scheduler.weekly.weekdays.at("09:00")

# Cron 表达式
@scheduler.cron("0 9 * * MON-FRI")  # 工作日9点
@scheduler.cron("*/15 * * * *")     # 每15分钟

# 一次性任务
@scheduler.once(60)                  # 60秒后执行一次
@scheduler.at("2026-12-25 00:00:00") # 指定时间执行

# 时区支持
@scheduler.daily.at("09:00", tz="Asia/Shanghai")

任务控制

# 超时 & 重试(指数退避)
@scheduler.every(5).minutes.timeout(30).retries(3)
def flaky_api_call():
    ...

# 暂停 / 恢复 / 取消
scheduler.pause_job("job_0")
scheduler.resume_job("job_0")
scheduler.cancel_job("job_0")

生产配置

scheduler = FastScheduler(
    storage="sqlmodel",                    # 持久化到数据库(默认 json 文件)
    database_url="sqlite:///scheduler.db", # 或 postgresql://...
    max_workers=20,                        # 并发任务数
    max_history=5000,                      # 最大历史记录数
    history_retention_days=8,              # 历史保留天数
    max_dead_letters=500,                  # 最大失败记录数
)

控制面板 API

面板自带 REST API,可用于外部集成:

端点 方法 说明
/scheduler/api/jobs GET 所有任务列表
/scheduler/api/jobs/{id}/pause POST 暂停任务
/scheduler/api/jobs/{id}/resume POST 恢复任务
/scheduler/api/jobs/{id}/run POST 立即执行
/scheduler/api/history GET 执行历史
/scheduler/api/dead-letters GET 失败队列