Technique

웹서비스 비동기(백그라운드) 프로세스 만들기 (feat. Django, Celery) 1

JAY-GO 2018. 3. 27. 22:53
반응형

상업용 웹서비스들은 오랜 시간(사용자가 인지할 만한 시간)이 필요한 프로세스의 경우 사용자의 명령을 받아 백그라운드로 처리하고 그 시간동안 사용자는 가만히 기다릴 필요 없이 다른 작업을 진행할 수 있도록 다른 서비스로 전환한다.


웹에 공개하기 위한 서비스에서 사용자 경험을 향상시키기 위해서는 이와 같은 백그라운드 처리는 필수적이다.


본 포스팅에서는 Django의 프로세스를 Celery를 이용해 비동기(백그라운드)화 하는 방법을 소개하고자 한다.


진행을 위한 셋팅은 본 블로그의 포스팅 Google Cloud, Docker로 간단하게 웹서비스 구축하기(feat. Django) 3 [2. 이제 dockerfile을 빌드 합니다.] 에서부터 시작합니다.

 * 비동기를 위해 사용하는 Celery 패키지는 윈도우를 지원하지 않기 때문에 Linux 사용을 위해 docker의 컨테이너를 활용합니다.


위 포스팅 까지 마치시면 Django 프로젝트 및 기타파일의 구성은 화면과 같습니다.



1. docker 컨테이너와 호스트 폴더 연결을 dockerfile 작성

 기존에 포스팅에서 작성한 dockerfile은 VOLUME 설정이 되어 있지 않기 때문에 그대로 빌드 후 컨테이너를 구동하면 호스트 컴퓨터에서 변경한 내용이 컨테이너에 반영되지 않습니다. 또한 컨테이너 구동 시 서버가 바로 시작하도록 작성되어 있으므로 테스트를 위해 이 부분도 수정합니다.

<dockerfile>

FROM ubuntu:18.04

MAINTAINER DEV-GO

RUN apt-get update -y && \
apt-get install -y \
nginx \
python3-dev \
python3-pip

RUN pip3 install django uwsgi

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm -rf /etc/nginx/sites-enabled/default
COPY mysite_nginx.conf /etc/nginx/sites-enabled/mysite_nginx.conf

#COPY . /mysite/
VOLUME /mysite/

WORKDIR /mysite/

#RUN chmod +x /mysite/docker_start.sh
#CMD /mysite/docker_start.sh && tail -f /dev/null


EXPOSE 80

프로젝트 폴더를 복사하던 라인을 주석처리하여 동작하지 않도록 하고,  컨테이너에 프로젝트 파일들이 위치해야할 폴더를 VOLUME 대상으로 설정하였습니다. 컨테이너가 동작 하자마자 서버가 동작하도록 작성한 스크립트도 동작하지 않도록 하였습니다.


2. 이제 dockerfile을 빌드 하고 실행합니다.

 ㅇ Docker CLI로 프로젝트 폴더에 접근하여 build 명령을 시행합니다.

PS C:\users\dev\pycharmprojects\docker_django_celery> docker build --tag docker_django_celery:0.1 .

docker build 명령은 dockerfile의 내용을 빌드하여 docker 이미지를 만들어 줍니다. 맨 뒤의 . 은 현재 위치에 dockerfile이 있음을 의미하므로 꼭 입력해야 합니다.

 ㅇ Docker 이미지 생성 확인

PS C:\users\dev\pycharmprojects\docker_django_celery> docker images

REPOSITORY                                  TAG                 IMAGE ID            CREATED             SIZE

docker_django_celery                    0.1                 15934f40e080        2 months ago        489MB

 ㅇ 생성한 이미지로 컨테이너 실행

PS C:\users\dev\pycharmprojects\docker_django_celery> docker run -it --name django_celery docker_django_celery:0.1

 우리가 사용할 컨테이너가 완성 되었습니다. 우측 하단에 우리의 프로젝트가 동작할 볼륨 위치가 있습니다. 볼륨의 설정버튼을 통해 로컬의 프로젝트 폴더와 연결해주면 호스트 개발환경과 컨테이너의 연결이 완료 됩니다.


3. 컨테이너 동작 확인

 우리가 만든 컨테이너가 호스트의 django 프로젝트와 잘 연결되어 동작 하는지 확인 해봅시다. 

 ㅇ 호스트 웹에서 컨테이너의 웹 페이지에 접속하기 위해 컨테이너의 개방된 포트와 호스트의 ip주소를 연결 해줍니다. Setting - Hostname/Ports - Configure Ports 에서 PUBLISHED IP의 포트를 설정해주고 save를 하면 컨테이너가 재 가동되고, 이제 해당 ip주소와 포트를 통해 컨테이너에서 구동중인 서버의 웹페이지에 접속이 가능합니다.

 ㅇ 이제 컨테이너에서 서버를 구동하기 위해 Kitematic의 EXEC를 통해 컨테너안에서 서버를 동작시켜 봅시다. 이전 포스팅에서 만들어서 프로젝트에 포함시켰던 docker_start.sh 스크립트를 실행해 봅시다.

# sh docker_start.sh

*** Starting uWSGI 2.0.15 (64bit) on [Tue Mar 27 14:24:57 2018] ***

compiled with version: 7.2.0 on 17 January 2018 14:22:13

os: Linux-4.4.89-boot2docker #1 SMP Wed Sep 27 22:59:39 UTC 2017

nodename: 629b4d182cdc

machine: x86_64

clock source: unix

detected number of CPU cores: 1

current working directory: /mysite

detected binary path: /usr/local/bin/uwsgi

!!! no internal routing support, rebuild with pcre support !!!

uWSGI running as root, you can use --uid/--gid/--chroot options

*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***

*** WARNING: you are running uWSGI without its master process manager ***

your processes number limit is 1048576

your memory page size is 4096 bytes

detected max file descriptor number: 1048576

lock engine: pthread robust mutexes

thunder lock: disabled (you can enable it with --thunder-lock)

uwsgi socket 0 bound to UNIX address /tmp/mysite.sock fd 3

Python version: 3.6.4 (default, Dec 27 2017, 13:02:49)  [GCC 7.2.0]

*** Python threads support is disabled. You can enable it with --enable-threads ***

Python main interpreter initialized at 0x55593c4379b0

your server socket listen backlog is limited to 100 connections

your mercy for graceful operations on workers is 60 seconds

mapped 72760 bytes (71 KB) for 1 cores

*** Operational MODE: single process ***

 * Starting nginx nginx                                                                                                 WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x55593c4379b0 pid: 15 (default app)

*** uWSGI is running in multiple interpreter mode ***

spawned uWSGI worker 1 (and the only) (pid: 15, cores: 1)

 이제 컨테이너 에서 nginx 서버가 동작하고 있습니다. 

 ㅇ 웹 접속 확인


4. 호스트와 컨테이너 연결 확인

 앞의 방법으로 호스트의 프로젝트와 컨테이너가 연결 되었다고 이야기 했습니다. 실제 그러한지 호스트 프로젝트의 내용을 바꾸어 컨테이너에서 동작중인 웹에 반영되는지 확인 해보겠습니다.

 ㅇ 일단 에러메시지가 보기 싫으니 django에 아무 주소로나 접속해도 오류가 뜨지 않도록 해봅시다.

<mywebapp/settings.py>

ALLOWED_HOSTS = ['*']

settings.py의 ALLOWED_HOST에 '*'를 추가하여 모든 주소에 대하여 django 프로젝트로의 접속을 허용 하도록 하였습니다.

 ㅇ 변경된 내용이 반영되도록 기존의 콘솔창을 닫고 새로 EXEC 콘솔을 통하여 서버를 실행해 봅시다.

# sh docker_start.sh

 에러 메시지가 사라지고 정상적인 django의 동작 화면을 볼 수 있습니다.


 다음 포스팅에서는 지금까지 준비한 컨테이너 환경에 비동기(백그라운드) 프로세스가 구현되는 것을 확인하기 위한 간단한 django 서비스를 만들어 보도록 하겠습니다.



반응형