数据库支持的异步任务队列

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次)
  • > MyxRuniTime >最大可能的任务运行时间,在此之后任务将被解锁并再次尝试(默认为3600秒)

任务错误

如果任务失败,并且错误记录在最后一个错误中(并记录在案),则会重试任务。由于任务可能是暂时性问题,例如暂时性网络问题,因此将重试该任务。但是,每次重试任务时,都会根据尝试的次数,使用指数后退,在以后重试:

(attempts ** 4) + 5

这意味着最初任务将在几秒钟后重试。四次尝试之后,261秒后(大约4分钟)再次尝试该任务。在25次尝试时,这项任务将在近4天内不再尝试!暂时性错误持续很长时间并非闻所未闻,此行为旨在停止触发错误的任务不断地(即由于编码错误)形成主导任务处理。您可能应该监视任务队列以检查是否有错误的任务。在最大尝试次数之后,任务将被标记为失败,并且不再重新安排。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java为什么stripVersion不能在带有mojo依赖项的mavendependencyplugin上工作   java存储具有不同功能的大量对象   java Spring MockMvc自定义验证器未在Spring容器中注册/调用   javascript程序编辑实体而不是添加   C++如何在java上检索图形卡信息?   java如何在没有方法参数的方法上使用@cacheable注释的键   java如何获取特定用户或学生的JSON   java可序列化AjaxRequestTarget   java Tomcat 8禁用分块编码过滤器   java这个简单的Swingbase类是线程安全的吗?   java调用Gdi32。使用JNA获取对象   如何使用来自其他类Java Android onClick的方法?   json序列化已经有了id(java.lang.String)的POJO   java使用jsp上传多个文件?   java有没有办法为Android项目在EclipseIndigo上设置JVM参数?   Eclipse中的java,为什么它告诉我添加一个已经存在的分号?   Java中的正则表达式拆分行   Java:在单行中赋值