날짜: 2024-11-27
Django + Celery 프로젝트에서 Celery Task가 먹통이 되는 상황을 방지하려면, Task Timeout 설정과 자동 종료 처리를 설정해야 합니다.
아래는 이러한 문제를 예방하기 위한 주요 설정과 방법입니다.
time_limit
(Hard Limit)을 설정합니다.from celery import shared_task
@shared_task(time_limit=300) # 5분 (300초)
def my_task():
# Task Logic
pass
CELERY_TASK_TIME_LIMIT = 300 # 초 단위
from celery import shared_task
from celery.exceptions import SoftTimeLimitExceeded
@shared_task(soft_time_limit=300) # 5분
def my_task():
try:
# Task Logic
pass
except SoftTimeLimitExceeded:
# Graceful 종료
print("Task exceeded soft time limit and will terminate.")
CELERY_TASK_SOFT_TIME_LIMIT = 300 # 초 단위
Task 내에서 예상치 못한 상황을 대비해 예외 처리를 구현하세요.
from celery import shared_task
@shared_task
def my_task():
try:
# Task Logic
pass
except Exception as e:
# 예외 로깅
import logging
logging.error(f"Task failed: {e}")
raise e # 필요시 재시도를 위해 예외를 다시 던질 수 있음
Task 실패 시 재시도를 제한하거나 특정 조건에서만 재시도하도록 설정합니다.
from celery import shared_task
@shared_task(bind=True, max_retries=3, default_retry_delay=60) # 1분 대기 후 최대 3회 재시도
def my_task(self):
try:
# Task Logic
pass
except Exception as e:
# 예외가 발생하면 재시도
raise self.retry(exc=e)
CELERY_TASK_DEFAULT_RETRY_DELAY = 60 # 초 단위
CELERY_TASK_MAX_RETRIES = 3
celery -A your_project worker --concurrency=4
CELERY_WORKER_PREFETCH_MULTIPLIER = 1 # 한 번에 하나씩 가져오기
CELERY_ACKS_LATE = True
CELERY_TASK_REJECT_ON_WORKER_LOST = True
pip install flower
celery -A your_project flower
Celery Worker가 메모리 누수 등의 이유로 불안정해질 수 있으므로, 일정 Task를 처리한 후 Worker를 자동으로 재시작하도록 설정합니다.
celery -A your_project worker --max-tasks-per-child=100
Task 간 Deadlock을 방지하기 위해 Task 내부에서 Timeout이나 Lock을 구현하세요.
from celery.utils.log import get_task_logger
import redis
logger = get_task_logger(__name__)
@shared_task
def my_task():
client = redis.StrictRedis()
lock = client.lock("my_task_lock", timeout=300) # 5분
if not lock.acquire(blocking=False):
logger.warning("Task is already running.")
return
try:
# Task Logic
pass
finally:
lock.release()
CELERY_TASK_TIME_LIMIT = 300
CELERY_TASK_SOFT_TIME_LIMIT = 270
CELERY_ACKS_LATE = True
CELERY_TASK_REJECT_ON_WORKER_LOST = True
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
celery -A your_project worker --max-tasks-per-child=100