本文目录导读:

在 Django 中实现后台任务调度,有几种常见且成熟的方法,选择哪种取决于任务的复杂度、需要的持久化能力以及是否依赖外部服务。
使用 Celery(最推荐,功能最强大)
Celery 是 Python 最流行的分布式任务队列,与 Django 集成非常完善。
安装配置
pip install celery[redis] # 推荐使用 Redis 作为 Broker # 或 pip install celery[rabbitmq]
基本使用
项目目录结构:
myproject/
├── myproject/
│ ├── __init__.py
│ ├── celery.py
│ ├── settings.py
│ └── ...
├── myapp/
│ ├── tasks.py
│ └── ...
celery.py 配置:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
settings.py 添加配置:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_BEAT_SCHEDULE = {
'send-report-every-30-minutes': {
'task': 'myapp.tasks.send_email_report',
'schedule': crontab(minute='*/30'),
},
}
tasks.py 定义任务:
from celery import shared_task
from django.core.mail import send_mail
@shared_task
def send_email_report():
send_mail(
'每日报告',
'这是你的每日报告内容。',
'from@example.com',
['to@example.com'],
)
return "任务完成"
@shared_task
def add(x, y):
return x + y
启动 Worker 和 Beat
# 启动 Worker(处理任务) celery -A myproject worker -l info # 启动 Beat(调度定时任务) celery -A myproject beat -l info # 同时启动 Worker 和 Beat(开发环境) celery -A myproject worker -B -l info
调用任务
# 异步调用
add.delay(4, 4)
# 延迟调用
from datetime import timedelta
add.apply_async((4, 4), countdown=10) # 10秒后执行
# 定时调用
from celery import current_app
current_app.send_task('myapp.tasks.add', args=[4, 4],
eta=datetime.now() + timedelta(hours=1))
使用 Django-Q(轻量级替代方案)
Django-Q 是一个原生 Django 任务队列,配置简单,不需要 Celery 那样的基础设施。
安装配置
pip install django-q
settings.py 配置:
INSTALLED_APPS = [
# ...
'django_q',
]
Q_CLUSTER = {
'name': 'myproject',
'workers': 4, # 并行工作进程数
'recycle': 500, # 每个 worker 处理任务数后重启
'timeout': 60, # 单个任务超时时间(秒)
'compress': True,
'save_limit': 250,
'queue_limit': 500,
'cpu_affinity': 1,
'label': 'Django Q',
'redis': {
'host': '127.0.0.1',
'port': 6379,
'db': 0,
}
}
# 定时任务配置
Q_CLUSTER['cron'] = [
# 每天凌晨3点执行
('0 3 * * *', 'myapp.tasks.daily_cleanup'),
]
定义任务
from django_q.models import Schedule
from django_q.tasks import async_task, schedule
def send_newsletter(user_id):
# 你的任务逻辑
return f"Newsletter sent to user {user_id}"
# 调用方式
async_task('myapp.tasks.send_newsletter', user_id=123)
# 定时执行
from datetime import timedelta, datetime
schedule(
'myapp.tasks.send_newsletter',
123,
schedule_type=Schedule.CRON,
cron_expression='0 0 * * *', # 每天午夜
next_run=datetime.now()
)
启动 Worker
python manage.py qcluster
使用 APScheduler(简单场景)
如果不想依赖外部服务,APScheduler 可以直接在 Django 进程中运行。
安装配置
pip install apscheduler
scheduler.py 设置:
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore
from django.conf import settings
def start_scheduler():
scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), 'default')
# 添加任务
scheduler.add_job(
my_task_function,
trigger='interval',
hours=1,
id='task_id',
replace_existing=True
)
scheduler.start()
return scheduler
集成到 Django
apps.py 中启动:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
def ready(self):
if not settings.DEBUG: # 生产环境才启动
from .scheduler import start_scheduler
start_scheduler()
使用 Huey(轻量级 Redis 队列)
Huey 是一个轻量级的任务队列,特别适合小项目。
pip install huey
配置:
from huey import RedisHuey
from huey.contrib.djhuey import task, periodic_task
from huey.crontab import crontab
huey = RedisHuey('myapp', host='localhost')
@periodic_task(crontab(minute='0', hour='3')) # 每天凌晨3点
def daily_backup():
# 备份逻辑
pass
@task()
def send_email_task(to, subject, body):
# 发送邮件
pass
选择建议
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Celery | 大型项目、复杂任务 | 功能完善、可靠性高、社区活跃 | 配置复杂、依赖较多 |
| Django-Q | 中型项目 | 配置简单、原生集成 | 功能较少、社区较小 |
| APScheduler | 简单定时任务 | 不依赖外部服务、轻量 | 不持久化、进程内运行 |
| Huey | 小项目快速开发 | 极简配置、性能好 | 只支持 Redis |
生产环境注意事项
-
任务重试:Celery 支持自动重试
@shared_task(bind=True, max_retries=3) def my_task(self): try: # 业务逻辑 pass except Exception as e: raise self.retry(exc=e, countdown=60) -
结果持久化:配置
result_backend存储任务结果 -
监控告警:使用 Flower(Celery)或自定义监控
-
任务优先级:Celery 支持设置队列优先级
-
限流:防止任务积压
CELERY_RATE_LIMITS = {'myapp.tasks.send_report': '1/m'} # 每分钟1次
对于大多数 Django 项目,我推荐从 Celery 开始,它是最成熟、最稳定的选择,如果项目较小或想快速上手,Django-Q 是个不错的轻量替代方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播