이럴 경우 proj/proj/celery.py 라는 파일을 새로 만들고 여기에 celery instance를 정의해주는 것을 추천한다.
proj/proj/celery.py
from __future__ import absolute_import, unicode_literals
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 module을 작성해줘야 한다. init.py를 작성해주면 이것은 django가 시작했을 때, app을 load해주고, @shared_task decorator를 사용가능하게 되는 것을 보장한다.
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',)
이제 celery.py에 있는 것을 하나씩 보자
from __future__ import absolute_import
이것은 celery.py module이 import 될 때 다른 library와 충돌되지 않도록 해준다.
위에 namespace를 설정해준 것은 celery 구성 옵션들이 모두 앞에 CELERY_가 붙게 되는 것을 의미한다. 예를 들면 broker_url 을 setting하면 이게 CELERY_BROKER_URL로 표시될 것이다. 이것은 worker setting에서도 적용되고, worker_concurrency가 CELERY_WORKER_CONCURRENCY로 표시 될 것이다.
그리고 일반적인 사항으로 재사용 가능한 앱은 모두 tasks.py에 빼서 정의하는 것이다. 그리고 celery에서는 이것은 자동적으로 찾아주는 모듈을 가지고 있다. => tasks.py에 celery tasks에서 반복적으로 재사용할 앱을 정의하라
app.autodiscover_tasks()
위의 줄을 추가해주면 celery가 자동적으로 tasks를 찾는데, 우리가 설치되어 있는 앱에서 찾는다.
19. 사이트 설정파일을 변경하여 기존의 스테틱 웹 서버에서 장고 애플리케이션이 구동하도록 변경
sudo vim /etc/nginx/sites-available/staticweb
이전에 이미 설정 완료!
upstream django {
server unix:/var/www/django/run/uwsgi.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
charset utf-8;
access_log /var/www/django/logs/access.log;
error_log /var/www/django/logs/error.log;
server_name _;
location = /favicon.ico {access_log off; log_not_found off; }
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
include /etc/nginx/uwsgi_params;
uwsgi_pass django;
}
}
EC2는 아마존에서 운영하는 서버이다. 정확히 Elastic Compute Cloud(EC2)는 안전하고 크기 조정이 가능한 컴퓨팅 파워를 클라우드에서 제공하는 웹 서비스입니다. 간단하게 생각하며 서버라고 생각하면 된다. 기존에 python에서 python manage.py runserver를 통해 간단한 서버를 운영할 수 있었는데 배포를 위해서는 아마존 EC2와 같은 서버를 운영해야 한다. 하지만 이것을 위해 먼저 큰 그림을 그리는 것이 정엉엉말 중요하다.
크게 EC2를 설정하기 위해서는 Nginx, uwsgi, django 3개에 대해 이해해야 한다.
먼저 Nginx , Nginx는 가장 먼저 클라이언트와 맞닥들이게 되는 웹서버라고 생각하면 쉽다. 이 웹서버에서 처리할 수 있는 일들을 처리를 하고 동적인 요청 혹은 데이터베이스에 대한 요청이 오면 그것은 django(웹 어플리케이션 서버)로 보내서 처리를 해야 한다.
그리고 그것을 중간에서 이어주는 미들웨어가 uwsgi다. 이렇게 그림을 먼저 그린 다음에 시작하면 쉽다.
크게 NGINX 와 UWSGI, DJANGO 3개를 합쳐서 EC2, 하나의 인스턴스로 생각하면 좀 더 쉽게 와닿을 수 있다.
따라서 먼저 Nginx를 설정해줘야 한다. 하나의 nginx에는 여러개의 설정파일을 설정할 수 있고, site-available한 설정파일들을 생성하고 이 설정파일들을 site-enable로 바꿔줌으로서 하나의 서버로 여러개의 웹사이트를 돌릴 수 있게 된다.
이 각각의 요청들은 nginx의 설정파일들에세 연결해준 servername을 통해 해당 django로 찾아가게 된다. 따라서 어떤 url로 오는지 연결하기 위해서는 IP와 ROUTE53을 통해 해당 url로 연결해주는 작업이 선행되어야 한다.
그렇게 하나의 서버에서 여러개의 설정파일들을 만들어내고 각각에 uwsgi와 django 어플리케이션을 연결하여 운영할 수 있다.
하지만 보통은 그렇게 하지 않는다. 하나의 EC2에 하나의 어플리케이션을 구동하도록 만들고, 리소스가 늘어나게 되면(즉 사용자가 많아지게 되면), 해당 EC2를 복사하여 여러개의 동일한 EC2를 생성해 낸다. 그리고 그 생성된 EC2들을 하나의 로드밸런서에 붙여 줌으로서 로드밸런스에서 적절히 분배해줌으로서 리소스가 몰리는 문제를 해결한다.
상황이 이렇다 보니 매번 새로운 서비스를 할 떄마다 EC2를 새롭게 설정해주는 것은 매우 비효율적이고 (실제적으로 servername만 바꾸어 주면 되므로) 이미지를 만들어 놓았다가 그 이미지를 인스턴스로 만들어서 해당 servername을 바꾸는 형태로 손쉽게 초기 테스트서버를 설정할 수 있다.
우리가 생성한 장고 파일은 EC2의 장고 파일에 업로드 시켜줘야 한다. 이때 이용하는 것이 FTP이다. 파일 전송 프로토콜(File Transfer Protocol, FTP)은 TCP/IP 프로토콜을 가지고 서버와 클라이언트 사이의 파일 전송을 하기 위한 프로토콜이다.
이를 통해 우리는 깃과 같은 소스관리를 거치지 않고 바로 EC2에 연결하여 업데이트 내용을 올릴 수 있게 된다.
여기서 또 하나의 문제점이 발생하게 되는데 여러개의 EC2를 운영하고 있다고 하면 어떻게 해야 할까? 한 곳의 EC2에 수정사항을 반영하게 되면 다른 EC2에는 반영이 안되는 상황이 발생하게 된다.
물론 가장 원초적으로 각각의 EC2에 접속하여서 하나 하나 바꾸어 주면 되지만 그것 역시 매우 비효율적이다. 따라서 하나의 인스턴스를 수정하면 그 인스턴스의 이미지를 복사하여 다시 새로운 인스턴스들을 생성한다.
한 번에 기존의 인스턴스들과 교체하게 되면 서버가 돌지 않는 순간이 발생하게 되므로 주의해야 한다.
따라서 기존의 인스턴스들과 함께 연결을 시킨이후에 잘 작동하는 것을 확인하고, 기존에 연결되어 있던 인스턴스들을 해체하는 순으로 작업을 완료시킨다.