Django + Celery + Elasticache(redis)


celery-beat패키지를 설치해 manage.py migrate django_celery_beat로 Django ORM을 이용해 Periodic task를 제어


celery_result_backend=django_db로 result를 orm으로 즉시 확인할 수 있게 한다

  1. Project app은 실행된다.
    djecommerce/init.py

from .celery import app as celery_app
__all__ = ('celery_app',)

  1. Project app에서 celery.py를 설정한다
from ____future____ import absolute_import
import os
from decouple import config
from celery import Celery
from celery.schedules import crontab
from django.conf import settings
DEBUG = config('DEBUG', cast=bool)
if DEBUG:
  os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djecommerce.settings.development')
else:
  os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djecommerce.settings.production')
app = Celery('djecommerce')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

djecommerce라는 name으로 Celery class 생성
settings에 지정되어있는 config 가져오기

@app.task(bind=True)
def dj_debug(self):
   print('Request: {0!r}'.format(self.request))
  1. autodiscover_tasks는 registered app/tasks.py 를 찾는다

user/tasks.py
auction/tasks.py
core/tasks.py

@app.task
Celery Class가 필요하다
@shared_task
가장 최근에 선언된 Celery Class를 가져다 쓴다(재사용성이 높은 앱에 쓰면 좋겠다)
@shared_task
def Phone_SMS_Send(phone, content):
	pass
  1. auction/views.py
Phone_SMS_Send.apply_async( args=[phone, content], ignore_result=False)
result = AsyncResult(task_id)
if result.ready():
	result.result

#Tips
Phone_SMS_Send.apply_async(kwargs={'foo':'bar'})

core/tasks.py
Phone_SMS_Send.apply(**kwargs):
	foo=kwargs['foo']
  1. djecommerce/settings/base.py

CELERY SETTING(broker_url, result_backend)
CACHE SETTING(Elasticache endpoint) & security group은 콘솔에서 직접
django_celery_results
django_celery_beat -> django orm에서 (python manage.py migrate django_celery_beat django_celery_result)

#CELERY
DJANGO_CELERY_BEAT_TZ_AWARE = False
REDIS_LOCATION_PRIMARY=config('REDIS_LOCATION_PRIMARY')
REDIS_LOCATION_REPLICA=config('REDIS_LOCATION_REPLICA')
CELERY_ALWAYS_EAGER = True
CELERY_BROKER_URL = f"redis://{REDIS_LOCATION_PRIMARY}"
# CELERY_BROKER_URL = "redis://127.0.0.1:6379/"
CELERY_RESULT_BACKEND = "django-db"
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = "Asia/Seoul"

CACHES = { 
    "default": { 
                "BACKEND": "django_redis.cache.RedisCache",
                "LOCATION": [ REDIS_LOCATION_PRIMARY, REDIS_LOCATION_REPLICA, ],
                "OPTIONS": { 
                    "CLIENT_CLASS": "django_redis.client.DefaultClient", 
                    "MASTER_CACHE": REDIS_LOCATION_PRIMARY, 
                    },
                } 
        }
       
INSTALLED_APPS={
    'django_celery_beat',
    'django_celery_results',
}
  1. elasticbeanstalk Procfile에서 celery 설정
web: gunicorn --bind :8000 djecommerce.wsgi:application
celery_worker: celery -A djecommerce.celery.app worker --concurrency=1 --loglevel=INFO -n worker.%%h
celery_beat: celery -A djecommerce.celery.app beat --scheduler django_celery_beat.schedulers:DatabaseScheduler --loglevel=INFO
  1. Elasticache instance 만들기
  • security group에 EB Security group추가
  • EC2 inbound rule에 6379 port로 상기 EB security group추가

DOCS
https://docs.celeryq.dev/en/latest/userguide/calling.html?highlight=apply_async#basics

좋은 웹페이지 즐겨찾기