Web server 개요
1. 클라이언트
웹서버(Nginx)로 HTTP 요청
2. 웹서버(Nginx)
웹 서버. 클라이언트로부터의 HTTP요청을 받아 정적인 페이지/파일을 돌려줌. (동적인 부분은 uWSGI가 담당) 가벼움과 높은 성능이 목표. 웹 서버, 리버스 프록시 및 메일 프록시 기능을 가짐.
3. Unix Socket
웹서버(Nginx) - 웹어플리케이션서버(uWSGI) 사이의 통신을 매개 HTTP 요청을 사용할 수도 있지만 서버 안쪽에서의 통신이기 때문에 socket 방식이 overhead가 적어서 더 효율이 좋음
4. 웹어플리케이션서버(uWSGI)
웹 서버(Nginx)와 웹 애플리케이션(Django)간의 연결을 중계 (Nginx에서 받은 요청을 Django에서 처리하기 위한 중계인 역할) Nginx는 Python을 모르기 때문에 uWSGI는 HTTP 요청을 python으로, Django로 부터 받은 응답을 Nginx가 알 수 있도록 변환해줌.
5. Django
웹 애플리케이션. 웹 요청에 대해 동적데이터를 돌려줌.
* WSGI
Web Server Gateway Interface파이썬에서 웹 서버와 웹 애플리케이션간의 동작을 중계해주는 인터페이스 표준 웹클라이언트의 HTTP 프로토콜 요청을 Python Call로 변환하기 위한 매핑관계로 WSGI를 표준으로 사용. uWSGI는 WSGI 표준의 구현
Django 프로젝트 생성 후 서버 실행시
./manage.py runserver (= python manage.py runserver)
하지만, 이것은 debug용으로 local에서만 사용해야 하고 실제 production 환경에서는 자제해야 함
Django 공식 문서에서도 production setting에서 사용하지 말라고 주의를 주고 있음
(보안 및 퍼포먼스 이슈 있을 수 있음)
그리고 두번째 줄에 보면 Django는 Web server가 아니라고 말함.
"우리는 웹 프레임워크를 만들지 웹 서버를 만드는 건 아니다. 그래서 실서버 환경에서 다룰 수 있는 건 Django의 영역 밖이다."
Django는 Web Server 가 아니라 Web Framework!
WSGI, uWSGI, uwsgi
일반적으로 웹 서버( Apache, Nginx )는 톰캣, PHP, Django, Node.js 등의 앞단에 배치되어 프록시, 보안, 정적 파일 제공 등의 역할을 함. 그런데 웹 서버는 PHP, Python, JavaScript 등의 언어를 해석할 능력이 없기 때문에 프로그래밍 언어를 해석할 수 있는 인터페이스, 즉 CGI가 필요함.
WSGI는 python 애플리케이션과 웹 서버가 통신하기 위해 정의된 표준 인터페이스. CGI와 WSGI는 웹 요청을 처리할 수 있는 표준 인터페이스 프로그램이라는 점에서 같지만, CGI는 WSGI보다 low level에 있음.
uWSGI는 애플리케이션을 처리 할 수 있는 애플리케이션 서버 컨테이너. WSGI 스펙에 정의 된 방법을 사용하여 python 애플리케이션과 통신하고, 프로토콜( 기본 프로토콜 : uwsgi )을 통해 다른 웹 서버와 통신함. 즉, 기존의 웹 서버에 대한 요청을 애플리케이션이 처리할 수 있도록 변환하는 부분.
uwsgi는 uWSGI가 웹 서버와 통신하기 위해 구현된 프로토콜. uWSGI를 통해 Nginx와 Django를 연동하고자 할 떄 Django에서 프로젝트를 생성하면 WSGI 프로세스를 사용할 수 있도록 정의된 wsgi.py 파일을 제공해주기 때문에 쉽게 연동이 가능함.
wsgi 분리
uwsgi 명령을 통해서 직접 웹어플리케이션 서버를 실행할때 사용할 설정 파일을 실행환경별로 분리(실행 환경별로 필요한 프로젝트 설정이 다르기 때문)
- base.py (공통)
- debug.py (개발용)
- deploy.py (배포용)
project_folder/
.config_secret/
settings_common.json
settings_debug.json
settings_deploy.json
django_app/
config/
settings/
__init__.py
base.py
debug.py
deploy.py
wsgi
__init__.py
debug.py
deploy.py
__init__py
urls.py
manage.py
..
wsgi/debug.py 예시
import osfrom django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.debug")
application = get_wsgi_application()
wsgi/deploy.py 예시
import osfrom django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.deploy")
application = get_wsgi_application()
runserver
- 장고는 DJANGO_SETTINGS_MODULE 환경변수를 통해서 참고할 settings 파일의 경로를 확인
- 환경변수가 설정되지 않으면 wsgi.py 의 설정값을 사용
- 혹은
python3 manage.py runserver
시에-settings
옵션을 통해서 지정 가능
# local development
python3 manage.py runserver --settings=config.settings.debug
# 환경변수 설정예시
export DJANGO_SETTINGS_MODULE=config.settings.debug
echo $DJANGO_SETTINGS_MODULE
wsgi.py
"""
WSGI config for qduoj project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oj.settings")
application = get_wsgi_application()
setting.py
production_env = get_env("OJ_ENV", "dev") == "production"
if production_env:
from .production_settings import *
else:
from .dev_settings import *
.
.
.
WSGI_APPLICATION = 'oj.wsgi.application'
Gunicorn
(Green UNICORN)
gunicorn은 Python WSGI HTTP Server. gunicorn은 상대적으로 빠르고 가볍고 사용이 쉬움.
- Automatic worker process management
- 간단한 Python configuration
- Multiple worker configurations
- 확장성(extensibility)을 위한 다양한 Server hook들
- python2.6+ 그리고 python3.2+ 과 호환 가능
Django에서는 wsgi.py에서 application = get_wsgi_application() 를 통해 wsgi handler를 가져옴.
wsgi handler에서는 middleware등 을 처리하고, WSGI server에서는 설정을 읽어 application의 경로를 가져옴.
Django 기본 명령어인 runserver 명령은 WSGI_APPLICATION 설정에서 경로를 가져옴.
Dramatiq
Dramatiq: 백그라운드 task processing을 도와주는 python 라이브러리
- 설치
$ pip install django-dramatiq-pg
- settings.py 중
INSTALLED_APPS
리스트에 추가INSTALLED_APPS = [ ... 'django_dramatiq_pg', ]
- Registry/tasks 생성
from django_dramatiq_pg.registry import Registry tasks = Registry() @tasks.actordef mytask(): ...
- 설정
DRAMATIQ_BROKER = { "OPTIONS": { "url": "postgres:///mydb", }, "MIDDLEWARE": [ "dramatiq.middleware.TimeLimit", "dramatiq.middleware.Callbacks", "dramatiq.middleware.Retries", ], } DRAMATIQ_REGISTRY = 'myapp.registry.tasks'
- worker process 시작
$ dramatiq django_dramatiq_pg.worker
'Web > Backend' 카테고리의 다른 글
Tools for load test (0) | 2021.06.10 |
---|---|
[백엔드 기초] 7. DB Parallelization (0) | 2021.06.01 |
[백엔드 기초] 5. Docker (0) | 2021.06.01 |
[백엔드 기초] 4. Database, PostgreSQL (0) | 2021.06.01 |
[백엔드 기초] 3. Django REST Framework (0) | 2021.06.01 |