Установить запланированную работу?

519

Я работал над веб-приложением с использованием Django, и мне любопытно, есть ли способ запланировать периодическое выполнение задания.

По сути, я просто хочу пробежаться по базе данных и делать некоторые вычисления / обновления на регулярной основе автоматически, но я не могу найти какую-либо документацию по этому вопросу.

Кто-нибудь знает, как это настроить?

Чтобы уточнить: я знаю, что могу настроить cronработу для этого, но мне любопытно, есть ли какая-то функция в Django, которая обеспечивает эту функцию. Я бы хотел, чтобы люди могли самостоятельно развернуть это приложение, не прибегая к настройке (желательно к нулю).

Я подумал о том, чтобы инициировать эти действия «задним числом», просто проверив, нужно ли было запускать задание с момента последней отправки запроса на сайт, но я надеюсь на что-то более чистое.

TM.
источник
1
Если вы высокопроизводительный сайт и уже используете RabbitMQ, вот хитрость для обхода cron: Использование AMQP для составления расписаний, подобных cron
Van Gale
Если я правильно понимаю, вам нужно запланировать некоторые задачи в Django. Лучшее, что я нахожу в эти дни, это: celery.github.com/celery/index.html
Али Никнешан,
Что ты думаешь об этом? github.com/reavis/django-cron
Доменико Монако
Тик, хотя, просто чтобы избежать вас всю эту работу. [Отказ от ответственности] Я строю галочку.
Сискиа
2
github.com/coleifer/huey Хьюи нуждается в упоминании здесь. Это нелепо легко настроить с помощью Django.
Брэндон Бертельсен

Ответы:

363

Одно из решений, которое я использовал, заключается в следующем:

1) Создайте пользовательскую команду управления , например

python manage.py my_cool_command

2) Используйте cron(в Linux) или at(в Windows) для запуска моей команды в требуемое время.

Это простое решение, которое не требует установки тяжелого стека AMQP. Тем не менее, есть некоторые преимущества использования чего-то вроде сельдерея, упомянутые в других ответах. В частности, с Celery было бы неплохо не распространять логику вашего приложения в файлы crontab. Однако решение cron довольно хорошо работает для приложений малого и среднего размера, где вам не нужно много внешних зависимостей.

РЕДАКТИРОВАТЬ:

В более поздней версии Windows atкоманда устарела для Windows 8, Server 2012 и выше. Вы можете использовать schtasks.exeдля того же использования.

**** ОБНОВЛЕНИЕ **** Это новая ссылка django doc для написания пользовательской команды управления

Брайан Нил
источник
5
Это способ сделать это без внешних сервисов, но с использованием только запущенного процесса Django Framework?
sergzach
4
Приложение @Brian_Neal django_cron.
sergzach
2
Пожалуйста, помогите мне понять, как я буду запускать команду управления в виртуальной среде с использованием cron в последний день каждого месяца.
mmrs151
2
@sergzach Я последовал за этим комментарием, и оказалось, что есть два пакета с этим именем. Джанго-хроны на Google Code и Джанго-хроны на Github . Они немного разные, но оба интересные. И то, и другое позволяет вам определять кроны по-джангонски. Первый немного старше и нацелен на работу без внешней задачи (т.е. cron). Второй, с другой стороны, требует, чтобы вы запускали python manage.py runcronsкрона, который затем запускает все кроны, которые вы определили и зарегистрировали.
Ловец снов
1
@sergzach Я полагаю, вы ссылаетесь на первый, "django-cron в Google Code". Вы правы насчет этого. Именно поэтому я выбрал второй вариант, «django-cron на GitHub», потому что он делает так, чтобы у вас была простая настройка / управление crontab - только один crontab, ссылающийся на команду управления - но так как вы используете отдельный В cron-процессе вы избегаете этой проблемы с синхронизацией (насколько я могу судить).
Driftcatcher
152

Celery - это распределенная очередь задач, построенная на AMQP (RabbitMQ). Он также обрабатывает периодические задачи в стиле крона (см. Периодические задачи ). В зависимости от вашего приложения, это может стоить того.

Celery довольно легко настроить с помощью django ( docs ), и периодические задачи фактически пропускают пропущенные задачи в случае простоя. У сельдерея также есть встроенные механизмы повтора, в случае неудачи.

DLN
источник
51

Мы с открытым исходным кодом, что я думаю, является структурированным приложением. это решение Брайана тоже намекает. Мы будем рады любым / всем отзывам!

https://github.com/tivix/django-cron

Он поставляется с одной командой управления:

./manage.py runcrons

Это делает работу. Каждый крон моделируется как класс (так что все его ОО), и каждый крон работает с разной частотой, и мы удостоверяемся, что один и тот же тип крона не работает параллельно (в случае, если самим кронам требуется больше времени, чем их частоте!)

chachra
источник
5
@chachra Извините, я знаю, что это может быть глупый вопрос, но будет ли он работать на Windows через atили был разработан специально для работы cron?
Бруно Палец
38

Если вы используете стандартную ОС POSIX, вы используете cron .

Если вы используете Windows, вы используете в .

Напишите команду управления Django

  1. Выясните, на какой платформе они находятся.

  2. Либо выполните соответствующую команду «AT» для своих пользователей, либо обновите crontab для своих пользователей.

С. Лотт
источник
10
Я хотел бы свернуть его в моем приложении Django, если это возможно.
ТМ.
@TM: Что означает «свернутый в мое приложение django»? Пожалуйста, уточните свой вопрос.
S.Lott
10
Мне бы хотелось, чтобы люди могли легко развертывать это приложение, не настраивая задачи cron самостоятельно.
ТМ.
1
Вы всегда можете обернуть интерфейс cron в свое приложение.
Monkut
BSD, Mac и любая Unix-подобная ОС имеют cron.
DylanYoung
23

Интересное новое подключаемое приложение Django: django-хронограф

Вам нужно только добавить одну запись cron, которая действует как таймер, и у вас есть очень приятный интерфейс администратора Django для запуска скриптов.

Ван Гейл
источник
2
Джанго-хронограф не поддерживается. Это вилка делает намного лучше: github.com/chrisspen/django-chroniker
Menda
16

Посмотрите на Cron Django Poor Man's, который является приложением Django, которое использует спам-ботов, роботов индексации поисковых систем и т. П. Для запуска запланированных задач примерно через равные промежутки времени.

Смотрите: http://code.google.com/p/django-poormanscron/

user41767
источник
2
Это также предполагает, что ваше приложение Django доступно из Интернета, что не относится к развертываниям в локальных и виртуальных сетях.
TimH - Codidact
10

Некоторое время назад у меня было точно такое же требование, и я решил его с помощью APScheduler ( Руководство пользователя )

Это делает планирование заданий очень простым и сохраняет его независимым от выполнения кода на основе запросов. Ниже приведен простой пример.

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()
job = None

def tick():
    print('One tick!')\

def start_job():
    global job
    job = scheduler.add_job(tick, 'interval', seconds=3600)
    try:
        scheduler.start()
    except:
        pass

Надеюсь, это кому-нибудь поможет!

PhoenixDev
источник
9

Предложение Брайана Нила о запуске команд управления через cron работает хорошо, но если вы ищете что-то более надежное (но не такое сложное, как Celery), я бы заглянул в такую ​​библиотеку, как Kronos :

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass
Йоханнес Горсет
источник
9

RabbitMQ и Celery имеют больше возможностей и возможностей для обработки задач, чем Cron. Если сбой задачи не является проблемой, и вы думаете, что будете обрабатывать сломанные задачи в следующем вызове, то Cron достаточно.

Celery & AMQP позволит вам справиться с неработающей задачей, и другой работник снова выполнит ее (рабочие Celery ожидают выполнения следующей задачи), пока не max_retriesбудет достигнут атрибут задачи . Вы даже можете вызывать задачи при сбое, например, регистрировать сбой или отправлять электронное письмо администратору послеmax_retries он будет достигнут.

И вы можете распространять серверы Celery и AMQP, когда вам нужно масштабировать ваше приложение.

Рави Кумар
источник
8

Лично я использую cron, но части планирования заданий в django-extensions выглядят интересно.

Ван Гейл
источник
Все еще зависит от cron для запуска, просто добавляет еще один уровень абстракции между ними. Не уверен, что оно того стоит, лично.
Карл Мейер
Я согласен, и, подумав об этом, я не хочу, чтобы промежуточное программное обеспечение замедляло работу моего сайта (аля бедняжка выше), когда cron все равно может сделать эту работу лучше.
Ван Гейл
7

Хотя Airflow не является частью Django, это более свежий проект (по состоянию на 2016 год), который полезен для управления задачами.

Airflow - это система автоматизации и планирования рабочих процессов, которую можно использовать для создания и управления конвейерами данных. Веб-интерфейс предоставляет разработчику ряд возможностей для управления и просмотра этих конвейеров.

Воздушный поток написан на Python и построен с использованием Flask.

Airflow был создан Maxime Beauchemin в Airbnb и открыт с весны 2015 года. Он присоединился к программе инкубации Apache Software Foundation зимой 2016 года. Вот страница проекта Git и некоторая дополнительная справочная информация .

Александр
источник
6

Поместите следующее в начало вашего файла cron.py:

#!/usr/bin/python
import os, sys
sys.path.append('/path/to/') # the parent directory of the project
sys.path.append('/path/to/project') # these lines only needed if not on path
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'

# imports and code below
Мэтт Маккормик
источник
6

Я просто подумал об этом довольно простом решении:

  1. Определите функцию представления do_work (req, param) так же, как и в любом другом представлении, с отображением URL, верните HttpResponse и так далее.
  2. Установите задание cron с вашими настройками синхронизации (или с помощью AT или запланированных задач в Windows), которое запускает curl http: // localhost / your / mapped / url? Param = value .

Вы можете добавить параметры, но просто добавив параметры в URL.

Скажите мне, что вы, ребята, думаете.

[Update] Я сейчас использую команду runjob из django-extensions вместо curl.

Мой cron выглядит примерно так:

@hourly python /path/to/project/manage.py runjobs hourly

... и так далее ежедневно, ежемесячно и т. д. Вы также можете настроить его для запуска определенной работы.

Я нахожу это более управляемым и более чистым. Не требует сопоставления URL-адреса с представлением. Просто определите свой класс работы и crontab, и все готово.

Майкл
источник
1
Единственная проблема, которую я чувствую, - это необязательно добавлять нагрузку на приложение и пропускную способность, просто чтобы запустить фоновое задание, которое лучше запускать «внутри» и независимо от обслуживающего приложения. Но, кроме этого, это умный и более общий django-cron, потому что он может даже вызываться агентами, внешними по отношению к серверу приложения!
nemesisfixx
Вы правы, поэтому я перешел на использование заданий из django-command-extensions. Смотрите мое обновление к моему ответу.
Майкл
4

после части кода я могу написать что угодно, как и мои views.py :)

#######################################
import os,sys
sys.path.append('/home/administrator/development/store')
os.environ['DJANGO_SETTINGS_MODULE']='store.settings'
from django.core.management impor setup_environ
from store import settings
setup_environ(settings)
#######################################

от http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/

xiaohei
источник
3

Вы обязательно должны проверить Django-Q! Он не требует дополнительной настройки и, возможно, имеет все необходимое для решения любых производственных проблем коммерческих проектов.

Он активно развивается и очень хорошо интегрируется с django, django ORM, mongo, redis. Вот моя конфигурация:

# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
    # Match recommended settings from docs.
    'name': 'DjangoORM',
    'workers': 4,
    'queue_limit': 50,
    'bulk': 10,
    'orm': 'default',

# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,

# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,

# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,

# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,

# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,

# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
    'sentry': RAVEN_CONFIG,
},
}
saran3h
источник
3

Джанго APScheduler для планировщика рабочих мест. Advanced Python Scheduler (APScheduler) - это библиотека Python, которая позволяет планировать выполнение кода Python позднее, либо один раз, либо периодически. Вы можете добавлять новые рабочие места или удалять старые на лету, как вам угодно.

примечание: я автор этой библиотеки

Установите APScheduler

pip install apscheduler

Просмотр файловой функции для вызова

имя файла: scheduler_jobs.py

def FirstCronTest():
    print("")
    print("I am executed..!")

Настройка планировщика

сделайте файл execute.py и добавьте следующие коды

from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

Ваши написанные функции Здесь, функции планировщика написаны в scheduler_jobs

import scheduler_jobs 

scheduler.add_job(scheduler_jobs.FirstCronTest, 'interval', seconds=10)
scheduler.start()

Свяжите файл для выполнения

Теперь добавьте строку ниже в нижней части файла URL

import execute
Чандан Шарма
источник
2

У меня было что-то похожее с твоей проблемой сегодня.

Я не хотел, чтобы он обрабатывался сервером через cron (и большинство библиотек в итоге были просто помощниками cron).

Итак, я создал модуль планирования и прикрепил его к init .

Это не лучший подход, но он помогает мне хранить весь код в одном месте, а его выполнение связано с основным приложением.

Фабрицио Бузето
источник
2

Да, метод выше, так здорово. И я попробовал некоторые из них. Наконец-то я нашел такой метод:

    from threading import Timer

    def sync():

        do something...

        sync_timer = Timer(self.interval, sync, ())
        sync_timer.start()

Так же, как рекурсивный .

Хорошо, я надеюсь, что этот метод может удовлетворить ваши требования. :)

Ни Сяони
источник
1
Остановится, если ваше «что-то» не получится, поэтому убедитесь, что вы обрабатываете все исключения внутри него. Даже тогда, веб-сервер может в какой-то момент убить ваш поток, не так ли?
Лутц Пречелт
2

Более современное решение (по сравнению с Celery) - Django Q: https://django-q.readthedocs.io/en/latest/index.html

Он имеет отличную документацию и легко прогуливается. Поддержка Windows отсутствует, поскольку Windows не поддерживает разветвление процессов. Но это прекрасно работает, если вы создаете свою среду разработки, используя подсистему Windows для Linux.

devdrc
источник
Кажется, вы все еще можете использовать его в режиме одного кластера в Windows
Yushin Washio
1

Я использую сельдерей для создания своих периодических заданий. Сначала вам нужно установить его следующим образом:

pip install django-celery

Не забудьте зарегистрироваться django-celeryв настройках, и тогда вы сможете сделать что-то вроде этого:

from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
 #your code
Дэвид Фелипе Камарго Поло
источник
2
Я заметил, что этот совет устарел, и вы можете интегрировать сельдерей напрямую. Смотрите pypi.python.org/pypi/django-celery для подробностей.
Питер Бриттен
В документации по сельдерею говорится, что это изменение в версии 3.1. Я сам еще не пробовал.
Питер Бриттен
1

Я не уверен, что это будет полезно для всех, так как мне пришлось предоставлять другим пользователям системы для планирования заданий, не предоставляя им доступ к фактическому планировщику задач сервера (windows), я создал это приложение многократного использования.

Обратите внимание, что пользователи имеют доступ к одной общей папке на сервере, где они могут создавать необходимые файлы command / task / .bat. Эта задача может быть запланирована с помощью этого приложения.

Название приложения Django_Windows_Scheduler

Скриншот: введите описание изображения здесь

just10minutes
источник
0

Если вы хотите что - то более надежное , чем сельдерей , попробуйте TaskHawk , который построен на вершине AWS SQS / SNS .

См .: http://taskhawk.readthedocs.io

Sriram
источник
0

Для простых докеризованных проектов я не мог найти подходящий ответ.

Поэтому я написал очень скромное решение без необходимости использования внешних библиотек или триггеров, которое работает само по себе. Не требуется внешний os-cron, он должен работать в любой среде.

Это работает путем добавления промежуточного программного обеспечения: middleware.py

import threading

def should_run(name, seconds_interval):
    from application.models import CronJob
    from django.utils.timezone import now

    try:
        c = CronJob.objects.get(name=name)
    except CronJob.DoesNotExist:
        CronJob(name=name, last_ran=now()).save()
        return True

    if (now() - c.last_ran).total_seconds() >= seconds_interval:
        c.last_ran = now()
        c.save()
        return True

    return False


class CronTask:
    def __init__(self, name, seconds_interval, function):
        self.name = name
        self.seconds_interval = seconds_interval
        self.function = function


def cron_worker(*_):
    if not should_run("main", 60):
        return

    # customize this part:
    from application.models import Event
    tasks = [
        CronTask("events", 60 * 30, Event.clean_stale_objects),
        # ...
    ]

    for task in tasks:
        if should_run(task.name, task.seconds_interval):
            task.function()


def cron_middleware(get_response):

    def middleware(request):
        response = get_response(request)
        threading.Thread(target=cron_worker).start()
        return response

    return middleware

models/cron.py:

from django.db import models


class CronJob(models.Model):
    name = models.CharField(max_length=10, primary_key=True)
    last_ran = models.DateTimeField()

settings.py:

MIDDLEWARE = [
    ...
    'application.middleware.cron_middleware',
    ...
]
yspreen
источник
0

Простой способ - написать собственную команду оболочки, см. Документацию Django и выполнить ее, используя cronjob в linux. Однако я очень рекомендую использовать брокер сообщений, такой как RabbitMQ, в сочетании с сельдереем. Может быть, вы можете взглянуть на этот учебник

Hamfri
источник