일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 트라이 #trie #알고리즘
- pycon
- bulk update
- 가사 검색
- 보행자 천국
- 불량 사용자
- 프로그래머스
- Spring Boot
- 카카오 인턴
- trie
- Python
- 튜플
- 징검다리 건너기
- 호텔 방 배정
- 알고리즘
- Tistory
- 티스토리 open api
- 크레인 인형뽑기 게임
- CleanCode
- jdbc
- 티스토리
- Open API
- 트라이
- Today
- Total
택시짱의 개발 노트
django 토이 프로젝트에 docker-compose로 celery + rabbitmq + flower 적용해보기 (회고 느낌) - 2 본문
django 토이 프로젝트에 docker-compose로 celery + rabbitmq + flower 적용해보기 (회고 느낌) - 2
택시짱 2022. 3. 1. 18:281편 - django 토이 프로젝트에 git action, code cov 적용해보기 (회고 느낌) - 1
오늘은 docker-compose를 이용하여 비동기 아키텍처를 구성해 보려고 합니다. (celery + rabbitmq + flower)
먼저 개념들에 대해 간단하게 알아보고 가시죠
비동기란?
비동기 방식은 현재 작업의 응답과 다음 작업의 요청이 동시에 진행되지 않아도 되는 것으로 응답에 관계없이 바로 다음 동작이 실행되는 것
celery란?
celery는 분산 메시지 전달에 기반한 비동기 작업 queue로써 별도로 실행 중인 Worker Process가 Broker로부터 Message를 전달 받아 작업을 대신 수행해 주는 라이브러리이다.
rabbitmq란?
RabbitMQ는 AMQP(Advanced Message Queueing Protocol)을 구현한 오픈소스 메세지 브로커(중개자)이다. 간단히 말해서 Rabbit MQ는 데이터를 일단 어딘가에 쌓아두고 나중에 비동기적으로 적절한 처리를 하고 싶은 경우를 위한 데이터 저장소이다.
(출처 - https://jithub.tistory.com/443)
flower란?
celery 클러스를 모니터링하고 관리하기 위한 웹 기반 도구이다. celery events를 사용하여 실시간 모니터링을 제공한다.
(출처 - https://flower.readthedocs.io/en/latest/)
일단 나는 docker를 이용하여 위의 동작과정에서 필요한 부분을 구성하려고 했다.
사실 docker에 대한 전문적인 지식이 없어 Dockerfile, docker-compose.yml 파일을 보는순간 왜 이렇게 했을까 라는 고민이 드실수 있습니다ㅠㅠ 좋은 방법 또는 방향이 있다면 댓글로 남겨주세요
django Dockerfile
Django의 Dockerfile은 아래와 같습니다.
# Django의 Dockerfile
FROM python:3.7.9
RUN apt-get update
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
COPY . /code
WORKDIR /code
RUN mkdir /static
RUN mkdir /staticfiles
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements/requirements-dev.txt
RUN python manage.py migrate
RUN python manage.py collectstatic --noinput
docker-compose.yml 코드
저는 docker-compose를 이용하여 DB를 제외한 서버의 모든 구성요소를 docker container를 이용하였습니다.
# DB를 제외한 서버 구성 요소 (nginx, django, redis, rabbitmq, celery(worker, beat), flower)
version: "3"
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
volumes:
- .:/code
- ./nginx:/etc/nginx/conf.d
- ./static:/static
depends_on:
- django
django:
build:
context: .
dockerfile: Dockerfile
container_name: djnago
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- .:/code
environment:
- DEV_NAME=${DEV_NAME}
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
- PASSWORD=${PASSWORD}
- HOST=${HOST}
- PORT=${PORT}
- USER=${USER}
- REDIS_HOST=redis
- CELERY_BROKER_URL=amqp://guest:guest@rabbitmq
depends_on:
- rabbitmq
- celery_worker
- redis
redis:
container_name: redis_service
image: redis
ports:
- "6379:6379"
volumes:
- .:/code
rabbitmq:
container_name: rabbitmq
image: rabbitmq:3.7.14-management-alpine
environment:
- RABBITMQ_USER=guest
- RABBITMQ_PASSWORD=guest
ports:
- "5672:5672"
- "15672:15672"
expose:
- "15672"
volumes:
- .:/code
celery_beat:
restart: always
build:
context: .
dockerfile: Dockerfile
command: "celery -A config beat --loglevel=info"
volumes:
- .:/code
environment:
- DEV_NAME=${DEV_NAME}
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
- PASSWORD=${PASSWORD}
- HOST=${HOST}
- USER=${USER}
- PORT=${PORT}
- CELERY_BROKER_URL=amqp://guest:guest@rabbitmq
depends_on:
- rabbitmq
celery_worker:
restart: always
build:
context: .
dockerfile: Dockerfile
command: "celery -A config worker --loglevel=info"
volumes:
- .:/code
environment:
- DEV_NAME=${DEV_NAME}
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
- PASSWORD=${PASSWORD}
- HOST=${HOST}
- USER=${USER}
- PORT=${PORT}
- CELERY_BROKER_URL=amqp://guest:guest@rabbitmq
depends_on:
- rabbitmq
flower:
image: mher/flower
environment:
- CELERY_BROKER_URL=amqp://guest:guest@rabbitmq
- FLOWER_PORT=5555
ports:
- 5555:5555
docker-compose 실행!
celery worker, beat의 구성은 django의 구성과 거의 흡사한데
django에서 비동기 작업을 queue로 던지면 django의 구성요소와 동일한 녀석이 worker로 동작하여 작업을 처리하면 되지 않을까 라는 생각을 가져서 django의 구성과 동일하게 하였습니다.
위의 docker-compose.yml파일을 실행 시키면 아래와 같이 각각의 container가 생성 되는것을 확인할 수 있습니다.
CONTAINER ID IMAGE
a165a0f5c931 nginx:latest
2ef40f0419e7 django_shopping_mall_api_project_django
1ce11a3247ea django_shopping_mall_api_project_celery_worker
1f2fd3bad67e django_shopping_mall_api_project_celery_beat
211a245decc6 rabbitmq:3.7.14-management-alpine
34f5bda1c66d mher/flower
5c3e185db6c2 redis
비동기 처리 테스트 코드
이제 비동기 처리를 할수 있는 인프라가 구축이 되었고, 간단하게 테스트를 해보겠습니다.
100까지 반복문을 돌면서 rabbitmq에 queue가 쌓이는것을 확인해보기 위해 time.sleep(1)을 주었습니다.
간단하게 views.py를 만들고 Postman으로 비동기 함수를 호출할 수 있게 했습니다.
# tasks.py
@app.task(bind=True)
def do_calc_total(self):
total = 0
for i in range(100):
time.sleep(1)
total += i
return total
# views.py
@decorators.api_view(['GET'])
def celery_test_view(request):
do_calc_total.delay()
return Response()
비동기 작업 시작전 상태 확인!
API를 호출하기 전에 rabbitmq, flower에서 현재 작업상태를 확인할 수 있습니다.
rabbitmq에는 queue가 비어 있는 것을 확인할 수 있고
flower에는 현재 동작하고 있는 woker가 없는것을 확인할 수 있습니다.
API를 이용하여 비동기 작업 실행!
현재 worker의 갯수는 4개로 설정을 해놓아 4개의 worker가 active인것을 확인할 수 있다.
이미 5개나 완료된것을 볼수있다.
위에서 worker의 갯수는 4개 queue에 쌓인 작업들을 소비하지 못해
ready에 job이 쌓여 있는것을 확인할 수 있다.
마무리
ec2위에 덕지덕지 install하며 비동기 처리를 해본적이 있는데 docker로는 처음 해봤는데 확실히 무지성으로 install하고 따라치면서 했던것 보다는 docker-compose.yml을 작성하면서 흐름을 파악할 수 있었던거 같았다.
docker-compose는 다른분이 보셨을때 부족한점이 많을것으로 생각되지만.. 구축했다는 것으로 만족..
서버 개발을 하며 비동기 처리를 왜쓰고 어디서 쓰는지를 조금씩 배워가고있다. 예를들면 인증번호 발송, 마케팅 email발송, 월말 또는 분기별 데이터 취합 등등..
그리고 현재 worker가 4개로 한정이 되어 있는데 대기하고 있는 job queue가 많으면 aws의 autoscaling과 같이 유동적으로 worker의 갯수를 늘리는 방법이 있는지 찾아보면 좋을것 같다.
예를들면 대기하고 있는 job queue가 10개 이상이면 worker의 갯수를 5개로 늘리고, 30개 이상이면 7개, 50개 이상이면 10개 등등...
docker container를 이용한다면 쿠버네티스를 써야되나?? 그냥 container를 늘리면되나?
'Django(장고)' 카테고리의 다른 글
django 토이 프로젝트에 git action, code cov 적용해보기 (회고 느낌) - 1 (0) | 2022.02.03 |
---|---|
29장 - 유틸리티들에 대해 (0) | 2022.01.26 |
25장. 비동기 태스크 큐 (0) | 2021.12.09 |
24장. 장고 성능 향상시키기 (0) | 2021.12.08 |
19장. 장고 어드민 이용하기 (2) | 2021.11.08 |