跳转到主要内容

Django的定时任务管理应用

项目描述

django-cronman

概述

Django应用,用于在Python级别定义和管理周期性任务。

安装

django-cronman可以使用pip直接从PyPI安装

pip install django-cronman

您还可以安装它,以便使用Cron远程管理器,同时安装附加依赖项。

pip install django-cronman[redis]

定义一个新的cron作业

Cron作业定义受Django Admin配置的启发。要添加新作业,您必须在应用内创建cron_job.py文件,在其中创建BaseCronJob子类并注册它

from cronman.job import BaseCronJob, cron_job_registry

class HelloWorld(BaseCronJob):
    """Demo Cron Job class"""

    def run(self):
        """Main logic"""
        pass

cron_job_registry.register(HelloWorld)

Cron作业类通过名称注册(并引用),这可以在注册时自定义

cron_job_registry.register(HelloWorld, name='Hello')

还可以检索或注销一个类(例如,在测试时)

cron_job_registry.get('HelloWorld')
cron_job_registry.unregister('HelloWorld')

如果给定应用中有多个cron作业,建议创建一个包而不是单个cron_jobs模块。每个类创建一个子模块,并在包的__init__.py中进行导入和注册。

配置cron作业

为确保cron作业定期执行,您需要向CRON_JOBS中添加条目。

CRON_JOBS = (
    ...
    # (<time spec>, <job spec>)
    # 'HelloWorld' will be executed a 5:15AM every day:
    ('   15   5   *   *   *', 'HelloWorld'),
)

CRONMAN_JOBS_MODULE设置为指定cron作业的模块的点分路径名。记住,此模块必须有一个CRON_JOBS属性。CRONMAN_JOBS_MODULE默认为None。例如

# settings_local.py

CRONMAN_JOBS_MODULE = 'app.cron_jobs.name'

运行调度器

settings.CRONMAN_JOBS_MODULE中定义的cron作业由cron应用的cron_scheduler命令启动。该命令构建一个应在当前周期(现在 +/- 1 分钟)执行的作业列表,并为每个作业创建一个新的子进程。

python manage.py cron_scheduler run

此命令应添加到运行定期任务的服务器的系统crontab中,并每2分钟执行一次。

运行单个cron作业

命令cron_worker run <job spec>负责执行cron作业。

python manage.py cron_worker run HelloWorld

cron作业参数

cron作业类可以接受参数,这些参数作为位置或命名参数传递给run方法。

class HelloWorld(BaseCronJob):
    """Demo Cron Job class"""

    def run(self, what, sleep=None):
        """Main logic"""
        print "Hello {}".format(what)
        if sleep:
            time.sleep(int(sleep))
    ...
python manage.py cron_worker run HelloWorld:world,sleep=5

参数作为字符串值传递,任何类型转换都应该在run方法中完成。支持带有空格的引号字符串,但逗号只能用作参数分隔符。

python manage.py cron_worker run HelloWorld:"big world",sleep=5

cronman.utils模块中存在用于提取列表和布尔值的实用函数。

配置Cronitor支持

cron_worker命令可以在作业启动、完成或失败时通知Cronitor。要启用此功能,您必须

  1. 在设置中启用Cronitor支持CRONMAN_CRONITOR_ENABLED = True
  2. 配置cron作业类
class HelloWorld(BaseCronJob):
    """Demo Cron Job class"""
    cronitor_id = 'ab12z'  # ID is assigned in Cronitor's dashboard

我们可以通过设置cronitor_ping_run = Falsecronitor_ping_fail = False来禁用在cron作业启动时发送可选的"RUN"和"FAIL"ping,但这似乎不是必要的。

重要提示:当在Cronitor仪表板上添加新的监控时,请使用类型heartbeat。避免使用cron job监控,因为它们会发送假阳性警报“未按计划运行”。

配置锁

任务可以获取锁以防止并发调用。锁的形式是位于settings.CRONMAN_DATA_DIR的PIDfiles。要为给定的cron作业类修改锁的行为,可以设置lock_type属性。

from cronman.taxonomies import LockType

class HelloWorld(BaseCronJob):
    """Demo Cron Job class"""
    lock_type = LockType.PARAMS

支持以下值:

  • None - 没有锁,允许并发
  • LockType.CLASS(默认)- 同时只能运行给定cron作业类的一个实例(例如,Foo:p=1Foo:p=2不能并发运行)
  • LockType.PARAMS - 同时只能运行一个类和参数的组合(例如,Foo:p=1Foo:p=2可以并发运行,但对另一个Foo:p=1的调用将被禁止)。由cron_worker命令获取和释放锁。

我们可以为几个cron作业类配置共享锁,以确保其中只有一个在运行。

from cronman.taxonomies import LockType

class HelloWorld1(BaseCronJob):
    """Demo Cron Job class (1)"""
    lock_type = LockType.CLASS
    lock_name = 'HelloWorld'

class HelloWorld2(BaseCronJob):
    """Demo Cron Job class (2)"""
    lock_type = LockType.CLASS
    lock_name = 'HelloWorld'

配置CPU和IO优先级

我们可以通过使用worker_cpu_priority属性为cron作业类分配CPU优先级(nice)。

from cronman.taxonomies import CPUPriority

class NiceHellowWorld(BaseCronJob):
    """Hello World running through `nice -n 19`"""
    worker_cpu_priority = CPUPriority.LOWEST

我们还可以通过将cronman.taxonomies.IOPriority中的某个值分配给worker_io_priority属性来自定义IO优先级(ionice),但在大多数情况下,这不是必要的,因为nice也会改变IO优先级。

命令cron_scheduler runcron_worker resume和cron作业RunCronTasks将根据分配给cron作业类的CPU和IO优先级启动工作进程。当运行cron_worker run时,这些设置**不会**强制执行,因此您必须手动将nice/ionice添加到此类调用中。

列出和杀死正在运行的cron作业

命令 cron_worker status 显示当前运行的 cron 作业 - PID 文件名、PID 和状态(《ALIVE》或《DEAD》)。可以通过 作业规范(cron 作业名称、参数)限制搜索结果。

python manage.py cron_worker status
python manage.py cron_worker status Foo
python manage.py cron_worker status Foo:bar=1

命令 cron_worker kill 可以优雅地(通过 SIGTERM)或强制杀死活跃的 cron 作业(当进程拒绝死亡时使用 SIGKILL)。可以通过 作业规范 限制任务列表。

python manage.py cron_worker kill
python manage.py cron_worker kill Foo
python manage.py cron_worker kill Foo:bar=1

可以使用 PID 杀死单个进程。

python manage.py cron_worker kill 39078

恢复 cron 作业

在杀死后,可以恢复 cron 作业的子集。

class ResumableHelloWorld(BaseCronJob):
    """Demo Cron Job class"""
    can_resume = True

命令 cron_worker resumecan_resume 功能启动所有已杀死的 cron 作业。

python manage.py cron_worker resume

要删除有关已死亡 cron 作业的所有条目并确保它们不会恢复,可以运行 cron_worker clean 命令。

python manage.py cron_worker clean

命令 cron_worker suspend 清除有关已死亡 cron 作业的所有先前条目,然后杀死所有正在运行的作业,以确保下一次 resume 只触发最近杀死的作业。

python manage.py cron_worker suspend

列出可用的 cron 作业

命令 cron_worker info 显示所有可用 cron 作业的列表。

python manage.py cron_worker info

当将 cron 作业名称传递给此命令时,系统将显示给定 cron 作业的 docstring 和参数。

python manage.py cron_worker info Foo

禁用调度器

调度器命令可以临时禁用。

python manage.py cron_scheduler disable

并稍后重新启用

python manage.py cron_scheduler enable

当调度器被禁用时,对 cron_scheduler run 的调用将不会启动工作进程。

将错误发送到 Sentry

cron 作业类中的错误被 cron_worker 拦截,并使用与其他 Django 命令相同的配置发送到 Sentry(settings.RAVEN_MANAGEMENT_COMMAND_CONFIG)。如果定义了 settings.CRONMAN_RAVEN_CMD,则调度器将使用它作为工作进程的执行脚本,例如 python manage.py cron_worker run Foo:bar=1 将转换为 {CRONMAN_RAVEN_CMD} -c "python manage.py cron_worker run Foo:bar=1"

Cron 任务 - 从管理区域运行 cron 作业

某些 cron 作业可以从管理区域请求启动:管理 > Cron > Cron 任务 要将 cron 作业类添加到管理区域的列表中,我们需要设置 ALLOWED_CRON_TASKS 设置。

ALLOWED_CRON_TASKS = (
    'HelloWorld',
)

要请求给定 cron 作业的另一次运行,我们只需在管理区域创建一个新的 CronTask 记录。调度器每 4 分钟启动一次 RunCronTasks cron 作业将为一个挂起的 Cron 任务启动一个单独的工作进程。

变更日志

2021-01-20 - 3.0.0 删除 Python 2 检查。修复暂停所有的问题。2020-05-25 - 2.1.0 Python 3 + Django 2 兼容性。2020-04-30 - 2.0.1 修复 sentry-sdk 问题。2020-04-23 - 2.0.0 用 sentry-sdk 替换 raven。2020-01-09 - 1.2.0 Django 2 兼容性。2019-04-30 - 1.1.1 Pre-commit.com 钩子支持。文档更新 2019-03-13 - 1.1.0 添加对 cronitor ping 的支持。2019-02-25 - 1.0.0 初始版本发布

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源分布

django-cronman-3.0.0.tar.gz (57.4 kB 查看散列)

上传时间

支持者