[part 3] push server (feat.Celery)

taek hwan Kwon
5 min readMay 20, 2019

--

Celery 란?

비동기 태스크 큐를 python 에서 사용할 수 있는 모듈

Celery는 왜 필요한가?

기본적으로 웹 서버는 프로세스를 동기적(Synchronous)으로 처리하기 때문에 다소 무거운 연산이나 오래 걸리는 작업의 경우 사용자는 웹 서버의 처리가 모두 마무리될 때까지 기다려야 하지만 오래 걸리는 작업은 비동기 처리 방식을 사용해 사용자가 해당 작업을 기다리지 않고 다른 작업을 진행할 수 있도록 사용자 측면에서의 속도 개선을 유도하기 위함

Celery 처리 구조

Django에서 task를 메세지 브로커(celery와 RabbitMQ가 궁합이 잘맞는다고 하나 이미 사용하고 있는 Redis 서버가 있어서 Redis를 씀)로 저장하면 Celery workers에서 해당 task 를 가져와 처리하고 처리한 내역을 Database 에 저장/업데이트 하는 구조

Celery for Django 메뉴얼

http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#using-celery-with-django

초기 프로젝트 구조

- Push_api/
- manage.py
- push_api/
- __init__.py
- settings.py
- urls.py

Push_api/push_api/init.py

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

Push_api/push_api/settings.py

INSTALLED_APPS = [
'django_celery_results', # Celery
'django_celery_beat',
]
# Celery 설정
# CELERY_TIMEZONE 는 django 설정값이 앞에 있어야 한다
CELERY_TIMEZONE = TIME_ZONE
CELERY_BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

Push_api/push_api/celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# `celery` 프로그램을 작동시키기 위한 기본 장고 세팅 값을 정한다.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
# @app 데코레이션 활성화
app = Celery('server')
# namespace='CELERY'는 모든 셀러리 관련 구성 키를 의미한다.
# 반드시 CELERY라는 접두사로 시작해야 한다.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Django App Config에 등록된 모든 taks 모듈을 불러온다.
app.autodiscover_tasks()
# celery 터미널 실행내용을 정의한다
@app.task(bind=True)
def debug_task(self):
print('Celery DATABASE Request: {0!r}'.format(self.request))

Push_api/push_api/celery.py

# Create your tasks here
from __future__ import absolute_import, unicode_literals
from celery import shared_task

@shared_task
def push_notification():
device.send()

Worker 실행하기 (백그라운드)

$ celery -A server worker -l info

추가적으로
주기적인 작업이 필요할 때는 Celery Beat 및 CronTab을 이용하면 됨
http://docs.celeryproject.org/en/latest/reference/celery.schedules.html#celery.schedules.crontab

모니터링 도구
flower, django-redisboard, django-rq

celery 공식 사이트
http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#using-celery-with-django
http://docs.celeryproject.org/en/latest/userguide/calling.html

--

--