예정된 작업을 설정 하시겠습니까?


519

Django를 사용하여 웹 응용 프로그램을 개발하고 있으며 주기적으로 작업을 예약하는 방법이 있는지 궁금합니다.

기본적으로 데이터베이스를 실행하고 자동으로 정기적으로 계산 / 업데이트를하고 싶지만이 작업에 대한 문서를 찾을 수없는 것 같습니다.

누구든지 이것을 설정하는 방법을 알고 있습니까?

명확히하기 위해 : cron이 작업을 수행 할 수 있다는 것을 알고 있지만 장고 에이 기능을 제공하는 기능이 있는지 궁금합니다. 사람들이 많은 구성 (바람직하게는 0)을 수행하지 않고도이 응용 프로그램을 직접 배포 할 수 있기를 바랍니다.

요청이 사이트에 마지막으로 전송 된 이후 작업이 실행되어야하는지 여부를 간단히 확인하여 이러한 작업을 "반복적으로"트리거하는 것을 고려했지만 조금 더 깨끗한 것을 원합니다.


1
고성능 사이트에 이미 RabbitMQ를 사용하고 있다면 cron을
Van Gale

내가 제대로 이해하면 장고에서 몇 가지 작업을 예약해야합니다. 요즘 가장 좋은 점은 다음과 같습니다. celery.github.com/celery/index.html
Ali Nikneshan

이것에 대해서 어떻게 생각하니? github.com/reavis/django-cron
Domenico Monaco

은이 모든 일을 피하기 위해되었습니다. [면책 조항] 나는 진드기를 만듭니다.
Siscia

2
github.com/coleifer/huey Huey에 대한 언급이 필요합니다. Django로 설정하는 것은 엄청나게 쉽습니다.
Brandon Bertelsen

답변:


363

내가 고용 한 해결책은 다음과 같습니다.

1) 만들기 사용자 지정 관리 명령을 , 예를 들어,

python manage.py my_cool_command

2) 사용 cron(Linux) 또는at 필요한 시간 (Windows)를 사용하여 명령을 실행하십시오.

이것은 무거운 AMQP 스택을 설치할 필요가없는 간단한 솔루션입니다. 그러나 다른 답변에서 언급 한 Celery와 같은 것을 사용하면 좋은 이점이 있습니다. 특히 Celery를 사용하면 응용 프로그램 논리를 crontab 파일로 분산시킬 필요가 없습니다. 그러나 크론 솔루션은 중소 규모의 응용 프로그램과 많은 외부 종속성을 원하지 않는 곳에서 매우 잘 작동합니다.

편집하다:

이후 버전의 Windows에서는이 at명령이 Windows 8, Server 2012 이상에서 더 이상 사용되지 않습니다. 당신이 사용할 수있는schtasks.exe같은 용도로 .

**** UPDATE **** 이것은 사용자 정의 관리 명령을 작성하기위한 django doc 의 새로운 링크 입니다.


5
외부 서비스가 없지만 django 프레임 워크 프로세스를 실행하는 유일한 방법입니까?
sergzach

4
@Brian_Neal django_cron 응용 프로그램.
sergzach

2
매월 마지막 날에 cron을 사용하여 가상 환경에서 관리 명령을 실행하는 방법을 이해하도록 도와주십시오.
mmrs151

2
@ sergzach 나는이 의견에 이어이 이름을 가진 두 개의 패키지가 있음을 알았습니다. Google 코드 장고 - 크론Github에서의 장고 - 크론 . 그것들은 약간 다르지만 둘 다 흥미 롭습니다. 둘 다 '장고'방식으로 크론을 정의 할 수 있습니다. 첫 번째는 조금 오래되어 외부 작업 (예 : cron)없이 작업하는 것을 목표로합니다. 반면 두 번째는 크론을 실행하도록 설정 한 python manage.py runcrons다음 정의하고 등록한 모든 크론을 실행 합니다.
driftcatcher

1
@sergzach 첫 번째 "Google 코드의 장고 크론"을 참조한다고 가정합니다. 당신은 그것에 대해 옳습니다. 이것이 실제로 두 번째 "GitHub의 django-cron"을 선택하는 이유입니다. 관리 명령을 참조하여 간단한 crontab 설정 / 관리-단 하나의 crontab을 갖기 때문입니다. cron 프로세스이 동기화 문제를 피할 수 있습니다 (알 수있는 한).
driftcatcher

152

Celery 는 AMQP (RabbitMQ)를 기반으로하는 분산 작업 대기열입니다. 또한 주기적 작업을 크론과 같은 방식 으로 처리합니다 ( 정기 작업 참조). ). 앱에 따라 정보를 얻을 가치가 있습니다.

Celery는 django ( docs )를 사용하여 설정하기가 매우 쉬우 며 정기적 인 작업은 실제로 가동 중지 시간이 발생할 경우 누락 된 작업을 건너 뜁니다. Celery에는 작업이 실패 할 경우를 위해 내장 된 재시도 메커니즘이 있습니다.


51

우리는 구조화 된 응용 프로그램이라고 생각하는 것을 오픈 소스했습니다. 브라이언의 해결책은 위와 같습니다. 우리는 모든 피드백을 좋아할 것입니다!

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

하나의 관리 명령이 제공됩니다.

./manage.py runcrons

그것은 일을한다. 각 크론은 클래스 (모두 OO)로 모델링되고 각 크론은 다른 빈도로 실행되며 동일한 크론 유형이 병렬로 실행되지 않도록합니다 (크론 자체가 주파수보다 실행하는 데 시간이 더 오래 걸리는 경우)!


5
@chachra 죄송합니다, 이것이 멍청한 질문 일지 모르지만 이것이 Windows에서 작동 at하거나 특별히 작동하도록 디자인 cron되었습니까?
Bruno Finger

38

표준 POSIX OS를 사용하는 경우 cron 을 사용합니다 합니다.

Windows를 사용 하는 경우 합니다.

장고 관리 명령을

  1. 그들이 어떤 플랫폼에 있는지 파악하십시오.

  2. 어느 사용자를위한 명령 "AT"적절한 실행, 또는 사용자의 crontab을 업데이트합니다.


10
가능하면 django 앱에 롤업하고 싶습니다.
TM.

@TM : "django 앱에 롤업"이란 무슨 의미입니까? 질문을 명확히하십시오.
S.Lott

10
사람들이 크론 작업을 직접 설정할 필요 없이이 응용 프로그램을 쉽게 배포 할 수 있기를 바랍니다.
TM.

1
언제든지 cron 인터페이스를 앱에 래핑 할 수 있습니다.
monkut

BSD, Mac 및 모든 유닉스 계열 OS에는 크론이 있습니다.
DylanYoung


16

스팸봇, 검색 엔진 인덱싱 로봇 등을 사용하여 일정 간격으로 예약 된 작업을 실행하는 Django 앱인 Django Poor Man 's Cron을 살펴보십시오.

참조 : http://code.google.com/p/django-poormanscron/


2
또한 웹에서 Django 앱에 액세스 할 수 있다고 가정합니다. LAN 및 VPN에 배포 할 경우에는 그렇지 않습니다.
TimH-Codidact

10

나는 얼마 전에 정확히 같은 요구 사항을 가지고 있었고 APScheduler ( User Guide)를 사용하여 해결했습니다. )를

스케줄링 작업을 매우 간단하게 만들고 일부 코드의 요청 기반 실행과 독립적으로 유지합니다. 다음은 간단한 예입니다.

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

이것이 누군가를 돕기를 바랍니다!


9

cron을 통해 관리 명령을 실행하는 Brian Neal의 제안은 잘 작동하지만 조금 더 강력한 것을 찾고 있다면 (Celery만큼 정교하지는 않지만) Kronos 와 같은 라이브러리를 살펴보십시오 .

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass

9

RabbitMQ와 Celery는 Cron보다 더 많은 기능과 작업 처리 기능을 가지고 있습니다. 작업 실패가 문제가되지 않고 다음 호출에서 깨진 작업을 처리 할 것으로 생각되면 Cron이면 충분합니다.

Celery & AMQP 를 사용하면 깨진 작업을 처리 할 수 ​​있으며 작업 max_retries속성에 도달 할 때까지 다른 작업자 (셀러리 작업자가 다음 작업을 수신 대기)에 의해 다시 실행됩니다 . 실패를 기록하거나 관리자에게 전자 메일을 보내는 등 실패시 작업을 호출 할 수도 있습니다.max_retries .

또한 응용 프로그램을 확장해야 할 때 Celery 및 AMQP 서버를 배포 할 수 있습니다.


8

나는 개인적으로 cron을 사용하지만 django-extensionsJobs Scheduling 부분 은 흥미로워 보입니다.


여전히 트리거링을 위해 cron에 의존하고 그 사이에 다른 추상화 계층을 추가하기 만하면됩니다. 개인적으로 가치가 있는지 확실하지 않습니다.
Carl Meyer

나는 그것에 대해 생각하고 나서 cron이 어쨌든 더 잘 할 수있을 때 미들웨어가 내 사이트 (위의 가난한 사람)를 늦추기를 원하지 않습니다.
Van Gale

7

Django, Airflow의 일부는 아니지만 는 작업 관리에 유용한 최신 프로젝트입니다 (2016 년 기준).

에어 플로우는 데이터 파이프 라인을 작성하고 관리하는 데 사용할 수있는 워크 플로우 자동화 및 스케줄링 시스템입니다. 웹 기반 UI는 개발자에게 이러한 파이프 라인을 관리하고 볼 수있는 다양한 옵션을 제공합니다.

기류는 Python으로 작성되었으며 Flask를 사용하여 빌드됩니다.

에어 플로우는 에어 비앤비의 Maxime Beauchemin이 2015 년 봄에 오픈 소스로 만들었습니다. 2016 년 겨울에 Apache Software Foundation의 인큐베이션 프로그램에 합류했습니다. 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. curl http : // localhost / your / mapped / url? param = value 를 실행하는 타이밍 환경 설정 (또는 Windows에서 AT 또는 예약 된 작업 사용)으로 크론 작업을 설정 하십시오 .

매개 변수를 추가 할 수 있지만 URL에 매개 변수 만 추가하면됩니다.

너희들이 어떻게 생각하는지 말해줘

[업데이트] django-extensions 에서 runjob 명령을 사용하고 있습니다. curl 대신 있습니다.

내 cron은 다음과 같습니다.

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

... 매일, 매월 등을 위해 '등등. 특정 작업을 실행하도록 설정할 수도 있습니다.

더 다루기 쉽고 깨끗합니다. URL을 뷰에 매핑 할 필요가 없습니다. 작업 클래스와 crontab을 정의하기 만하면됩니다.


1
감지하는 것은 단지 "내부적으로"서비스를 제공하는 앱과 독립적으로 더 나은 백그라운드 작업을 실행하기 위해 앱에로드와 불필요한 대역폭을 불필요하게 감지하는 것입니다. 그러나 그 외에는 앱 서버 외부의 에이전트가 호출 할 수 있기 때문에 영리하고 일반적인 장고 크론입니다!
nemesisfixx

당신이 옳습니다, 그래서 django-command-extensions에서 작업을 사용하는 것으로 옮겼습니다. 내 답변에 대한 내 업데이트를 참조하십시오.
Michael

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/


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,
},
}

3

스케줄러 작업을위한 Django APScheduler. APScheduler (Advanced Python Scheduler)는 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

나는 오늘 당신의 문제와 비슷한 것을 가지고있었습니다.

나는 서버 trhough cron에 의해 처리되기를 원하지 않았습니다 (그리고 대부분의 라이브러리는 결국 cron 도우미였습니다).

그래서 예약 모듈을 만들고 init에 첨부했습니다 .

가장 좋은 방법은 아니지만 모든 코드를 한곳에서 실행하고 주요 앱과 관련하여 실행하는 데 도움이됩니다.


2

예, 위의 방법은 너무 좋습니다. 그리고 나는 그들 중 일부를 시도했습니다. 마침내 다음과 같은 방법을 찾았습니다.

    from threading import Timer

    def sync():

        do something...

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

재귀 처럼 .

좋아,이 방법이 귀하의 요구 사항을 충족시킬 수 있기를 바랍니다. :)


1
'무언가'가 실패하면 중단되므로 모든 예외를 처리하십시오. 그럼에도 불구하고 웹 서버는 어떤 시점에서 스레드를 죽일 수 있습니다.
Lutz Prechelt

2

더 현대적인 솔루션 (셀러리와 비교)은 Django Q입니다. https://django-q.readthedocs.io/en/latest/index.html

훌륭한 문서를 가지고 있으며 이해하기 쉽습니다. Windows는 프로세스 포크를 지원하지 않기 때문에 Windows 지원이 부족합니다. 그러나 Windows for Linux Subsystem을 사용하여 개발 환경을 만들면 제대로 작동합니다.


당신이 할 것 같다 아직 사용 Windows에서 단일 클러스터 모드
유신 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 를 참조하십시오.
피터 브리튼

셀러리 문서 는 이것이 v3.1의 변경이라고 말합니다. 아직 직접 시도하지 않았습니다.
Peter Brittain

1

시스템의 다른 사용자에게 실제 서버 (Windows) 작업 스케줄러에 대한 액세스 권한을 부여하지 않고 작업을 예약하도록 제공해야했기 때문에 이것이 누군가에게 유용하다는 것을 확신하지 못합니다.이 재사용 가능한 앱을 만들었습니다.

노트 사용자는 필요한 명령 / 작업 / 박쥐 파일을 만들 수 있습니다 서버에 하나 개의 공유 폴더에 액세스 할 수 있습니다하십시오. 그런 다음이 앱을 사용하여이 작업을 예약 할 수 있습니다.

앱 이름은 Django_Windows_Scheduler

스크린 샷 : 여기에 이미지 설명을 입력하십시오



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',
    ...
]

0

간단한 방법은 사용자 정의 쉘 명령이 볼 작성하는 것입니다 장고 문서 와 리눅스에서 cron 작업을 사용하여 실행합니다. 그러나 셀러리와 연결된 RabbitMQ와 같은 메시지 브로커를 사용하는 것이 좋습니다. 이 자습서를 살펴볼 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.