이번에는 EC2와 Docker환경에서 django와 nginx 컨테이너가 띄워져 있는 환경에서
celery도 함께 세팅하고 이를 테스트해보겠습니다.
RabbitMQ, celery_worker, celery_beat 총 3개의 컨테이너를 더 추가해
총 컨테이너는 5개가 됩니다.
$ pip install celery
$ pip install django-celery-results
$ pip install django-celery-beat
# settings.py
# Application definition
INSTALLED_APPS = [
...
# celery
'django_celery_beat',
'django_celery_results',
]
# Celery
CELERY_BROKER_URL = 'AWS public DNS 주소'
CELERY_RESULT_BACKEND = 'django-db'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
...
version: '3'
services:
web:
container_name: web
build:
context: ./
dockerfile: Dockerfile.prod
command: gunicorn 프로젝트명.wsgi:application --bind 0.0.0.0:8000
environment:
DJANGO_SETTINGS_MODULE: 프로젝트명.settings.prod
env_file:
- .env
volumes:
- static:/home/app/web/static
- media:/home/app/web/media
expose:
- 8000
entrypoint:
- sh
- config/docker/entrypoint.prod.sh
nginx:
container_name: nginx
build: ./config/nginx
volumes:
- static:/home/app/web/static
- media:/home/app/web/media
ports:
- "80:80"
depends_on:
- web
rabbitmq:
container_name: rabbitmq
image: rabbitmq:3.7-alpine
environment:
- RABBITMQ_USER=guest
- RABBITMQ_PASSWORD=guest
ports:
- "5672:5672" # Default Port
- "15672:15672" # For UI
expose:
- "15672"
celery_worker:
container_name: celery_worker
build:
context: ./
dockerfile: Dockerfile.prod
ports: []
depends_on:
- web
- rabbitmq
command: sh -c "celery -A 프로젝트명 worker --loglevel=info"
celery_beat:
container_name: celery_beat
build:
context: ./
dockerfile: Dockerfile.prod
ports: []
depends_on:
- web
- rabbitmq
- celery_worker
command: sh -c "celery -A 프로젝트명 beat --loglevel=info"
volumes:
static:
media:
총 5개의 컨테이너를 띄울 겁니다.
(web, nginx, rabbitmq, celery_worker, celery_beat 총 5개의 컨테이너)
celery.py 는 프로젝트 디렉토리에,
task.py 는 앱 디렉토리 안에 위치해 있어야합니다.
# celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from celery.schedules import crontab
# 기본 장고파일 설정
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '프로젝트명.settings')
app = Celery('프로젝트명')
app.config_from_object('django.conf:settings', namespace='CELERY')
#등록된 장고 앱 설정에서 task 불러오기
app.autodiscover_tasks()
# task 함수 주기 설정
app.conf.beat_schedule = {
'api1': { # 스케쥴링 이름
'task': 'main.tasks.api1_update', # 수행할 task 설정
'schedule': crontab(minute=41, hour='*'), # 매 시각 41분마다 호출
},
}
# tasks.py
from __future__ import absolute_import, unicode_literals
from celery import shared_task
from dnd_7th_4_backend.celery import app
# api1 재호출 시 필요한 함수 -> update
@shared_task
def api1_update():
func1_update()
먼저 이렇게 5개의 컨테이너가 잘 빌드된 것을 확인할 수 있습니다.
그 다음에는 celery_beat 컨테이너의 로그를 찍어보면 다음과 같습니다.
ubuntu@ip-172-31-45-97:~$ docker logs 33
[2022-08-13 09:30:03,620: INFO/MainProcess] beat: Starting...
[2022-08-13 09:41:00,059: INFO/MainProcess] Scheduler: Sending due task api1 (main.tasks.api1_update)
[2022-08-13 10:41:00,049: INFO/MainProcess] Scheduler: Sending due task api1 (main.tasks.api1_update)
[2022-08-13 11:41:00,041: INFO/MainProcess] Scheduler: Sending due task api1 (main.tasks.api1_update)
보면 스케줄러가 등록해놓은 task를 등록한 시간마다 보내고 있는 것을 확인할 수 있습니다.
celery_worker의 컨테이너를 확인해볼까요?
celery_worker 컨테이너의 로그를 찍어보면 다음과 같습니다.
.
.
.
[2022-08-13 11:43:41,744: INFO/ForkPoolWorker-1] Task main.tasks.api1_update[850e0f56-ed8d-482d-a6ef-52e9dc67140f] succeeded in 161.69972267199773s: None
결과 출력창 맨 마지막만 확인해보면 다음과 같습니다.
task를 수행했고, 성공했으며 결린 시간이 함께 나와있습니다.
제가 등록한 task를 통해서
데이터베이스의 결과가 업데이트 되었음을 직접 확인할 수 있었습니다🙆🏻♀️