数据库支持的异步任务队列
django-background-task的Python项目详细描述
django background task是Django的基于数据库的工作队列,松散地基于ruby的DelayedJob库。
在django后台任务中,所有任务都作为函数(或任何其他可调用的)实现。
使用后台任务有两部分:
- 创建任务函数并将其注册到调度程序中
- 设置cron任务(或长时间运行的进程)以执行任务
创建和注册任务
要注册任务,请使用后台装饰程序:
from background_task import background from django.contrib.auth.models import User @background(schedule=60) def notify_user(user_id): # lookup user by id and send them a message user = User.objects.get(pk=user_id) user.email_user('Here is a notification', 'You have been notified')
这将把notify_用户转换为后台任务函数。当您从常规代码调用它时,它实际上会创建一个任务对象并将其存储在数据库中。然后,该数据库包含有关稍后实际需要运行哪个函数的序列化信息。这确实限制了调用函数时可以传递的参数-它们必须都可以序列化为json。因此,在上面的示例中,为什么传递的是用户id而不是用户对象。
正常调用notify_user将计划在60秒后运行原始函数:
notify_user(user.id)
这是默认的计划时间(在decorator中设置),但可以覆盖它:
notify_user(user.id, schedule=90) # 90 seconds from now notify_user(user.id, schedule=timedelta(minutes=20)) # 20 minutes from now notify_user(user.id, schedule=datetime.now()) # at a specific time
运行任务
有一个管理命令可以运行已计划的任务:
python manage.py process_tasks
这只需每隔几秒钟轮询数据库队列,查看是否有新任务要运行。
注意:为了帮助管理任务找到注册的任务,最好将它们放在名为“tasks.py”的文件中。您可以将它们放在其他地方,但必须确保它们将被导入,以便装饰器可以向调度程序注册它们。通过将它们放入tasks.py中,它们将被自动发现,并由管理命令自动导入文件。
process_tasks management命令有以下选项:
- 持续时间-在此时间内运行任务(0秒或更短时间将永远运行)-默认值为0
- 睡眠-在检查新任务(如果未找到任何任务)之前睡眠此秒数-默认值为5
- 日志文件-日志文件目标
- 日志std-将stdout和stderr重定向到日志系统
- 日志级别-设置日志级别(严重、错误、警告、信息、调试)
您可以使用duration选项进行简单的流程控制,方法是通过cron作业运行管理命令,并将duration设置为cron再次调用该命令之前的时间。这样,如果命令失败,稍后cron作业将重新启动它。它还避免了过分担心资源/内存泄漏。另一种方法是使用像supervisord这样的成熟程序来处理这个问题。
设置
可以在settings.py文件中设置两个设置。
- 最大尝试次数-控制任务尝试的次数(默认为25次)
任务错误
如果任务失败,并且错误记录在最后一个错误中(并记录在案),则会重试任务。由于任务可能是暂时性问题,例如暂时性网络问题,因此将重试该任务。但是,每次重试任务时,都会根据尝试的次数,使用指数后退,在以后重试:
(attempts ** 4) + 5
这意味着最初任务将在几秒钟后重试。四次尝试之后,261秒后(大约4分钟)再次尝试该任务。在25次尝试时,这项任务将在近4天内不再尝试!暂时性错误持续很长时间并非闻所未闻,此行为旨在停止触发错误的任务不断地(即由于编码错误)形成主导任务处理。您可能应该监视任务队列以检查是否有错误的任务。在最大尝试次数之后,任务将被标记为失败,并且不再重新安排。