Django에서 Celery 사용하기
Celery는 task queue를 관리하는 파이썬기반 패키지임. 버전 4.2까지 나옴. 이전에는 Django와 Celery각각 개별 라이브러리로 세팅해야했는데 버전3.1부터는 Celery가 django와 통합되어서, 더 쉽게 이용가능해짐
Celery 설치는 아래와 같이 하고,
pip install 'celery[redis]'
django 의 settings.py가 있는 경로에 celery.py 생성
- proj/
- manage.py
- proj/
- __init__.py
- settings.py
- urls.py
# proj/proj/celery.py
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
app = Celery('proj')
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
# proj/proj/__init__.py
from __future__ import absolute_import, unicode_literals
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app
__all__ = ('celery_app',)
redis를 설치한다. celery가 일꾼이라면 redis는 broker로 일꾼에게 일을 전단하는 역할을 한다.
$ sudo yum install redis
$ pip install redis
$ pip install django-celery-beat
$ pip install django-celery-results
$ pip freeze
redis==2.10.6
celery==4.2.1
$ python manage.py migrate
# redis 설치 잘 됐는지 확인
$ redis-server
$ redis-cli ping
PONG
settings.py 에 broker정보를 추가한다.
CELERY_BROKER_URL = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Seoul'
INSTALLED_APPS += (
'django_celery_beat',
'django_celery_results',
)
Celery실행
# redis 실행된 상태에서 실행 해야함
$ sudo redis-server
$ celery -A proj worker -l info
$ celery -A proj beat -l info
$ celery -A proj flower --port=5555
flower는 celery monitoring도구임. http://localhost:5555 에 들가면 task, broker, resource 모니터링 가능함 (참고: http://docs.celeryproject.org/en/latest/userguide/monitoring.html)
참고로, celery multi 명령어를 이용하면 worker를 background에서 실행할 수 있다. (참고: http://docs.celeryproject.org/en/latest/getting-started/next-steps.html#next-steps)
## starting
$ celery multi start w1 -A proj -l info
celery multi v4.0.0 (latentcall)
> Starting nodes...
> w1.halcyon.local: OK
## restarting
$ celery multi restart w1 -A proj -l info
celery multi v4.0.0 (latentcall)
> Stopping nodes...
> w1.halcyon.local: TERM -> 64024
> Waiting for 1 node.....
> w1.halcyon.local: OK
> Restarting node w1.halcyon.local: OK
celery multi v4.0.0 (latentcall)
> Stopping nodes...
> w1.halcyon.local: TERM -> 64052
## stop
$ celery multi stop w1 -A proj -l info
또는
$ celery mullti stopwait w1 -A proj -l info
Task실행 해보기
$ python manage.py
>>> from proj.celery import debug_task
>>> debug_task.delay()
<AsyncResult: cb9f81d6-9a9a-4887-9333-491056e9d153>
>>> debug_task.apply_async(())
task (AsyncResult object) 상태는 아래와 같이 바뀜
Pending -> Started -> Retry -> Started -> Retry -> Started -> Success
django 프로젝트 내의 python 함수에 celery task를 데코레이터 (@shared_task, @ask) 를 붙이면 celery task로 관리 할 수 있음.