이전 글에서는 Django-Celery-Beat: PeriodicTask를 활용한 예약 작업 실전 예제 를 통해 IntervalSchedule을 이용한 예약 작업을 관리하는 방법을 살펴봤습니다.

하지만, 실전 프로젝트에서는 반복 실행(interval) 방식만으로는 부족한 경우가 많습니다.

  • 매일 특정 시간에 실행해야 하는 작업이 필요할 때
  • 특정 날짜와 시간에 단 한 번만 실행되는 작업이 필요할 때

이런 경우 Crontab 또는 Clocked 예약 방식을 사용하면 더욱 정교한 예약 작업을 설정할 수 있습니다. 🚀

📌 Crontab 개념이 익숙하지 않다면?

➡️ 리눅스 `crontab` 제대로 이해하기: 개발자가 사랑하는 자동 스케줄링 꿀팁

위 글을 먼저 읽고 오면 더욱 쉽게 이해할 수 있습니다! 😊

Django Celery-Beat task scheduling with Crontab and Clocked

1️⃣ `CrontabSchedule`을 활용한 특정 시각 예약

Crontab은 Linux에서 사용되는 예약 작업 방식으로, 초/분/시간/요일/날짜 등 특정 시간에만 실행되도록 설정할 수 있습니다.

Django-Celery-Beat에서도 `CrontabSchedule`을 활용하여 같은 방식으로 예약 작업을 설정할 수 있습니다.

📌 예제: 매일 오전 9시 30분에 실행되는 예약 작업

from django_celery_beat.models import PeriodicTask, CrontabSchedule
import json

# 1️⃣ CrontabSchedule 생성 (매일 09:30에 실행)
schedule, created = CrontabSchedule.objects.get_or_create(
    minute="30",
    hour="9",
    day_of_week="*",
    day_of_month="*",
    month_of_year="*"
)

# 2️⃣ PeriodicTask 생성 또는 업데이트
task, created = PeriodicTask.objects.update_or_create(
    name="daily_report_task",
    defaults={
        "crontab": schedule,  # CrontabSchedule 적용
        "task": "myapp.tasks.generate_daily_report",
        "args": json.dumps([]),
        "enabled": True,
    }
)

✅ 위 설정은 매일 오전 9시 30분에 실행되도록 예약됩니다! 🎯

✅ `CrontabSchedule` 필드 설명

필드명 설명 예시
`minute` 실행할 분 설정 "0", "30", "*/10"
`hour` 실행할 시간 설정 "0", "9", "*/6"
`day_of_week` 실행할 요일 설정 (0=Sunday) "*"(매일), `"1,3,5"`(월/수/금)
`day_of_month` 실행할 날짜 설정 "*"(매일), `"1,15"`(매월 1일, 15일)
`month_of_year` 실행할 월 설정 "*"(매월), `"1,6,12"`(1월, 6월, 12월)

2️⃣ `ClockedSchedule`을 활용한 특정 시간에 한 번만 실행

`ClockedSchedule`은 특정 날짜와 시간에 한 번만 실행되는 예약 작업을 설정하는 데 사용됩니다.

📌 예제: 특정 날짜(2025년 2월 10일 15:00)에 한 번만 실행되는 예약 작업

from django_celery_beat.models import PeriodicTask, ClockedSchedule
import json
from datetime import datetime

# 1️⃣ ClockedSchedule 생성 (2025년 2월 10일 15:00에 실행)
scheduled_time = datetime(2025, 2, 10, 15, 0)  # datetime 객체 사용 필수!
schedule, created = ClockedSchedule.objects.get_or_create(
    clocked_time=scheduled_time
)

# 2️⃣ PeriodicTask 생성 (one_off=True 설정!)
task, created = PeriodicTask.objects.update_or_create(
    name="one_time_task_20250210",
    defaults={
        "clocked": schedule,  # ClockedSchedule 적용
        "task": "myapp.tasks.one_time_email",
        "args": json.dumps([]),
        "enabled": True,
        "one_off": True,  # 실행 후 자동 비활성화
    }
)

✅ 위 설정은 2025년 2월 10일 15시 00분에 한 번만 실행된 후 자동으로 비활성화됩니다.

  • 📌 ClockedSchedule 모델의 인스턴스를 생성할 때, clocked_time 필드는 반드시 datetime 객체로 입력해야 합니다.
  • 📌 문자열이나 다른 데이터 타입을 사용하면 오류가 발생할 수 있습니다.

📌 ClockedSchedule과 one_off 옵션의 관계?

ClockedSchedule에서 한 번만 실행되는 작업을 만들 때 one_off=True를 설정하는데,
이 설정이 enabled 필드와 어떻게 상호작용하는지에 대해 궁금할 수 있습니다.

📌 이 두 개의 필드(clocked_timeone_off) 간의 관계에 대해 더 자세히 알고 싶다면?

➡️ Celery Beat에서 one-off와 enabled의 관계: 올바른 이해와 사용법

위 글에서 `one_off=True`가 정확히 어떻게 동작하는지, `enabled`와 어떤 차이가 있는지를 깊이 있게 다루고 있으니 참고해주세요! 😊

🎯 결론: CrontabClocked를 활용하면 더욱 정교한 예약 작업 가능!

  • CrontabSchedule을 사용하면 반복적이지만 특정 시각에 실행되는 작업을 예약할 수 있음!
  • ClockedSchedule을 사용하면 특정 시점에 한 번만 실행되는 작업을 예약할 수 있음!
  • ClockedSchedule 생성 시 clocked_time 필드는 반드시 datetime 객체로 입력해야 함!
  • ClockedScheduleone_off=True 설정 간의 관계는 별도의 포스트에서 더 깊이 있게 다루고 있으니 확인해 보세요!

더 깊이 있는 Celery 활용법을 알고 싶다면,

아래의 '유사 포스트' 목록이나, 우측 상단의 검색창에서 `"Celery"`를 검색해 보세요! 🚀 😊