웹 애플리케이션에서 사용자 등록과 같은 빠른 작업은 동기 방식으로 처리해도 문제가 없지만, 취약점 스캔이나 대용량 데이터 처리 같은 장시간 실행되는 작업의 경우 사용자가 몇 분 동안 응답을 기다리게 할 수 없습니다. 이러한 상황에서는 비동기 작업 처리가 필수적입니다.
Celery 소개
Celery는 Python으로 작성된 분산 작업 큐 시스템으로, 실시간 작업과 주기적 작업을 모두 지원합니다. Celery 아키텍처의 주요 구성 요소는 다음과 같습니다:
- Task - 실행할 작업 단위
- Broker - 작업 메시지를 중계하는 메시지 큐
- Worker - 큐에서 작업을 가져와 실행하는 소비자
- Beat - 주기적 작업 스케줄러
- Backend - 작업 실행 결과 저장소
환경 설정
Windows 환경에서는 Celery 3.1.24 버전을 사용해야 합니다:
pip install celery==3.1.24
pip install redis==2.10.6
Redis 서버를 로컬에 설치하고 실행해야 합니다.
Celery 애플리케이션 생성
# tasks.py
from celery import Celery
celery_app = Celery('async_tasks',
broker='redis://localhost:6379/0',
backend='redis://localhost:6379/0')
비동기 작업 정의
# tasks.py
@celery_app.task
def process_email_notification(user_email):
print(f"이메일 전송 시작: {user_email}")
import time
time.sleep(5) # 이메일 전송 시뮬레이션
return "이메일 전송 완료"
Worker 서비스 실행
celery -A tasks worker --loglevel=info
작업 호출 예제
# app.py
from tasks import process_email_notification
def handle_user_registration():
import time
start_time = time.time()
print("1. 데이터베이스에 사용자 정보 저장")
print("2. 비동기 이메일 전송 시작")
process_email_notification.delay("user@example.com")
print("3. 사용자에게 등록 완료 응답")
elapsed = time.time() - start_time
print(f"총 소요 시간: {elapsed:.2f}초")
if __name__ == '__main__':
handle_user_registration()
작업 디렉토리 구조:
project/
├── tasks.py
└── app.py
이메일 전송 작업이 백그라운드에서 비동기적으로 실행되기 때문에 메인 프로세스는 즉시 응답을 반환할 수 있습니다.
주요 이슈 및 해결방법
- Python 3.7과 Celery 3.x 호환성 문제: Python 3.6으로 다운그레이드
- Redis 버전 호환성: redis 2.10.6 버전 사용
- Windows 지원: Celery 3.1.24 버전 사용