Celery Beat는 Celery의 주기적 태스크 스케줄러로, 정해진 간격이나 crontab 스케줄에 따라 태스크를 자동으로 실행합니다.
Celery Beat는 크게 세 가지 요소로 구성됩니다.
Beat Scheduler — 주기적으로 태스크를 큐에 넣는 프로세스입니다. 단일 인스턴스로만 실행해야 중복 실행을 방지할 수 있습니다.
Worker — 큐에서 태스크를 꺼내 비동기로 실행하는 프로세스입니다. 여러 인스턴스를 띄울 수 있습니다.
Broker — Redis나 RabbitMQ 같은 메시지 브로커가 둘 사이를 연결합니다.
# celery.py
from celery import Celery
from celery.schedules import crontab
app = Celery('myapp', broker='redis://localhost:6379/0')
# 방법 1: beat_schedule 설정
app.conf.beat_schedule = {
# 매 30초마다 실행
'check-every-30s': {
'task': 'tasks.check_status',
'schedule': 30.0, # 초 단위
},
# crontab으로 매일 오전 7시 30분 실행
'morning-report': {
'task': 'tasks.send_report',
'schedule': crontab(hour=7, minute=30),
'args': ('daily',),
},
# 매주 월요일 오전 9시
'weekly-cleanup': {
'task': 'tasks.cleanup',
'schedule': crontab(hour=9, minute=0, day_of_week=1),
},
}
app.conf.timezone = 'Asia/Seoul'
# tasks.py
from celery import shared_task
@shared_task
def check_status():
# 비동기로 실행될 로직
return "checked"
@shared_task(bind=True, max_retries=3)
def send_report(self, report_type):
try:
# 실패 시 자동 재시도
generate_and_send(report_type)
except Exception as exc:
raise self.retry(exc=exc, countdown=60)
from celery.schedules import crontab, solar
from datetime import timedelta
# 1) 고정 간격 (timedelta)
'schedule': timedelta(minutes=5)
# 2) crontab 표현식
'schedule': crontab(minute='*/15') # 매 15분
'schedule': crontab(hour='9-17', minute=0) # 업무 시간 매 정시
'schedule': crontab(0, 0, day_of_month='1') # 매월 1일 자정
# 3) solar (일출/일몰 기반 - 특수 용도)
'schedule': solar('sunset', -37.81, 144.96)
# Worker 실행
celery -A myapp worker --loglevel=info
# Beat 실행 (별도 프로세스)
celery -A myapp beat --loglevel=info
# Worker + Beat 동시 실행 (개발용, 프로덕션 비권장)
celery -A myapp worker --beat --loglevel=info
Django를 쓴다면 django-celery-beat 패키지를 활용하면 Admin 페이지에서 스케줄을 동적으로 관리할 수 있습니다.
# settings.py
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
이렇게 하면 DB에 스케줄이 저장되어 서버 재시작 없이 스케줄을 추가/수정/삭제할 수 있습니다.
timezone 설정을 명시하지 않으면 UTC 기준으로 동작합니다.더 구체적인 부분(예: 동적 스케줄 관리, 태스크 체이닝, 에러 핸들링 등)에 대해 궁금한 점이 있으면 알려주세요.