서론
Nginx(엔진엑스)에 대해 찾아보는 와중 기존 내가 알고 있던 웹 서버(Web Server)에 대한 개념이 상충하는 것이 있어 이를 정리하고자 한다. 본 글에서는 Web Server와 WAS의 개념 비교부터 시작하여 가장 보편적으로 사용되는 Web Server 엔진 및 실제 사용될 수 있는 프로젝트 구성을 Docker-compose를 통해 구성해보고자 한다.
본론
Web Server
위키백과에 정의된 웹 서버에 대한 정의는 다음과 같다
웹 서버(Web server)는 다음의 두 가지 뜻 가운데 하나이다.
1. 웹 서버: 웹 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고, HTML 문서와 같은 웹 페이지를 반환하는 컴퓨터 프로그램
2. 웹 서버 (하드웨어): 위에 언급한 기능을 제공하는 컴퓨터 프로그램을 실행하는 컴퓨터
웹 서버(web server)는 HTTP 또는 HTTPS를 통해 웹 브라우저에서 요청하는 [HTML 문서나 오브젝트(이미지 파일 등)을 전송해주는 서비스 프로그램을 말한다. 웹 서버 소프트웨어를 구동하는 하드웨어도 웹 서버라고 해서 혼동하는 경우가 간혹 있다.
즉, 웹 서버란 HTTP, HTTPS 통신 프로토콜을 통해 사용자가 요청하는 HTML 문서나 오브젝트, 즉 정적인 파일들을 전달해주는 서비스 프로그램을 말한다. 다만 이러한 정적인 페이지들의 경우 과거에는 충분하였을 지 모르나 기술이 발달한 요즘 시대에는 부족한 것이 사실이다. 이러한 태생적인 한계를 극복하기 위한 것이 WAS(Web Application Server)이다.
WAS (Web Application Server)
마찬가지로 위키백과에 정의된 웹 어플리케이션 서버에 대한 정의는 다음과 같다
웹 애플리케이션 서버(Web Application Server, 약자 WAS)는 웹 애플리케이션과 서버 환경을 만들어 동작시키는 기능을 제공하는 소프트웨어 프레임워크이다. 인터넷 상에서 HTTP를 통해 사용자 컴퓨터나 장치에 애플리케이션을 수행해 주는 미들웨어(소프트웨어 엔진)로 볼 수 있다. 웹 애플리케이션 서버는 동적 서버 콘텐츠를 수행하는 것으로 일반적인 웹 서버와 구별이 되며, 주로데이터베이스 서버와 같이 수행이 된다. 한국에서는 일반적으로 "WAS" 또는 "WAS S/W"로 통칭하고 있으며 공공기관에서는 "웹응용 서버"로 사용되고, 영어권에서는 "Application Server" (약자 AS)로 불린다.
즉, 웹 애플리케이션 서버(WAS)는 우리가 통상적으로 인식하고 있는 웹 서버의 개념과 동일하다고 보면 된다. 사용자의 요청이 단순 정적인 파일 서빙으로 해결이 안 될 경우, 즉 사용자마다 서로 다른 페이지를 보여줘야 하거나 특정 비지니스 로직, 혹은 DB와의 상호작용이 필요한 경우가 이에 해당된다.
왜 구분하는가?
WAS는 Web Server와 Web Container로 이루어져 있다. 다만 통상적인 개발 과정에서는 WAS와 Web Server를 분리하여 개발하는 경우가 잦다. 아래와 같은 구조를 의미한다.
1차적으로 사용자가 요청한 내용을 Web Server에서 처리한다. 해당 요청이 단순 정적인 파일 서빙으로 해결될 수 있는 문제의 경우 Web Server가 자체적으로 해당 파일을 서빙하여 해결한다. 다만 비즈니스 로직이나 DB 조회가 필요한 동적인 파일의 경우 WAS에 요청하여 해당 요청을 처리한다.
이와 같은 구조로 구성할 경우 아래와 같은 장점을 얻을 수 있다.
1. WAS 서버 부하 방지
WAS 서버는 실제 비즈니스 로직 및 DB 조회를 담당하는데, 단순 정적 파일 또한 WAS에서 서빙할 경우 다른 작업으로 인해 불필요한 딜레이가 발생할 수 있다.
2. 로직 분리를 통한 보안 강화
일반적인 사용자들은 Web Server에만 접근하고 WAS는 알 필요가 없다. 따라서 사용자들에게 노출되는 부분은 Web Server로 한정지어 불필요한 위험으로부터 분리하여 비즈니스 로직 등 중요 데이터들을 안전하게 지킬 수 있다.
3. 다수의 WAS 서버 연결
동일한 서비스를 제공하는 복수의 WAS 서버를 연결하여 특정 서버에 가해지는 부하를 줄일 수 있다 (Load Balancing). 또한 특정 한 서버가 다운 되더라도 여분의 서버를 통해 안정적인 서비스를 제공할 수 있다 (Fail Over).
4. 여러 웹 어플리케이션과의 연결
서로 다른 기능을 담당하는 WAS를 연결하여 복수의 서비스를 제공할 수 있다.
Nginx
Nginx(엔진엑스)란 Web Server의 일종으로, 현재 가장 상용화된 방식 중 하나이다. 과거엔 Apahce(아파치)를 활용하여 Web Server를 구현하였는데, Apache는 쓰레드 방식으로 하나의 요청당 하나의 쓰레드가 새로 생성되어 해당 요청을 처리하는 방식이다. 이러한 방식의 경우 쓰레드를 생성하고 또 요청을 처리하기까지 많은 오버헤드가 발생하게 되어 사용에 꺼려지고 있다.
Nginx는 이와 대조적으로 사전 정의된 설정값(*.conf)에 따라 Worker Process가 생성되고, 이 Worker Process가 일정 시간(keep alive) 동안 유지되어 사용자의 요청(Connection)을 처리하는 방식이다. 이렇게 보면 Apache와 큰 차이가 없어 보이지만 가장 큰 핵심은 사용자의 요청을 비동기적으로 처리한다는 것이다. 사용자의 요청은 Queue에 대기상태로 쌓이고 유휴상태인 Worker Process가 해당 작업을 맡아 처리하는 방식이다. 이를 Event-Driven 방식이라 한다.
Nginx to WSGI
WSGI(위스키)는 Web Server Gateway Interface의 약자로, Web Server와 Python 기반의 WAS를 연결해주기 위한 통신 규약이다. 일반적인 Apache, Nginx와 같은 Web Server는 Python을 모르기 때문에 Django(장고)나 Flask(플라스크) 기반으로 구현된 WAS에 요청을 보낼 수 없다. WSGI는 그 사이에서 이를 중계해주는 역할이다.
가장 일반적으로 Django는 Gunicorn(지유니콘)을 사용한다. 다만 Django를 경험해본 사람들은 Gunicorn을 사용하지 않고도 Django 기반 백엔드 서버에서 HTTP 통신을 정상적으로 이루었을 것이다. 이는 python manage.py runserver 명령어를 통해 WAS를 실행할 경우 기본적으로 Django 내장 WSGI 서버를 통해 사용자의 HTTP 요청을 처리하기 때문이다. 그럼에도 불구하고 장고 내장 WSGI 서버가 아닌 Guicorn이란 별도의 WSGI 서버를 통해 요청을 처리하는 이유는 아래와 같다.
Gunicorn has many features that Django's built-in server is lacking:
- gunicorn can spawn multiple worker processes to parallelize incoming requests to multiple CPU cores
- gunicorn has better logging
- gunicorn is generally optimized for speed
- gunicorn can be configured to fine grades depending on your setup
- gunicorn is actively designed and maintained with security in mind
실습
실습은 Docker-compose를 통해 Postgres, Django, Nginx 각각에 해당하는 Docker Container를 만들어 구성된 환경에서 진행되었다. 본 실습은 Docker-compose를 통해 각 Container 간의 연결에 초점을 맞춘 관계로 Django 프로젝트 설정에 관한 내용은 생략하도록 하겠다. local_settings.py를 통해 DB 관련 설정을 해주었단 것만 주의하면 큰 문제는 없을 것이다. 프로젝트 디렉토리 구조는 아래와 같다.
# > tree
.
├── bin
│ ├── compose
│ │ ├── django
│ │ │ └── Dockerfile
│ │ └── nginx
│ │ └── nginx.conf
│ ├── docker-compose.yml
│ ├── requirements.txt
│ └── restart_docker.sh
└── practice
├── manage.py
├── practice
│ ├── __init__.py
│ ├── asgi.py
│ ├── local_settings.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py # Django 기본 WSGI 서버
└── practice_site
├── __init__.py
├── admin.py
├── apps.py
├── fixtures
│ └── initial_data.json
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── tests.py
├── urls.py
└── views.py
Docker 컨테이너 구성을 위한 docker-compose.yml 파일은 아래와 같다.
# ./bin/compose/docker-compose.yml
version: '3'
services:
practice_database: # DB 서비스
container_name: practice_database
image: postgres:15
environment:
- POSTGRES_DB=practice
- POSTGRES_USER=practice
- POSTGRES_PASSWORD=practice
practice_web: # Django 서비스
container_name: practice_web
build:
context: .
dockerfile: ./compose/django/Dockerfile # 별도의 Dokcerfile을 통해 빌드
volumes:
- ..:/app # docker-compose 기준 상대참조하여 /app 디렉토리 내부로 마운트
working_dir: /app/practice
command: >
sh -c "
echo yes | python manage.py collectstatic && # static 파일을 빌드하기 위한 명령어
wait-for-it.sh practice_database:5432 && # DB 설정 완료까지 대기
python manage.py makemigrations &&
python manage.py migrate &&
python manage.py loaddata initial_data.json &&
gunicorn sweat.wsgi:application --workers=20 --timeout=300 --bind 0.0.0.0:8000
"
depends_on:
- practice_database
practice_nginx: # Nginx 서비스
container_name: practice_nginx
image: nginx:latest
ports:
- "80:80"
volumes:
- ../practice/static:/static # collectstatic 명령어를 통해 빌드된 파일을 마운트
- ./compose/nginx:/etc/nginx/conf.d # conf 설정 파일 마운트
depends_on:
- practice_web
Docker-compose 구성에 사용된 Dockerfile 및 nginx.conf는 아래와 같다
# .bin/compose/django/Dockerfile
FROM python:3.10.6
ENV PYTHONUNBUFFERED 1
RUN apt-get update -y
# wait-for-it 스크립트를 통해 데이터베이스 설정 완료를 보장
RUN wget -O /usr/local/bin/wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh
# 디렉토리 설정 및 필수 패키지 설치
WORKDIR /app
ADD requirements.txt /app/
RUN pip install --upgrade pip \
&& pip install -r requirements.txt
# ./bin/compose/nginx/nginx.conf
server {
listen 80;
server_name practice_web;
location / {
proxy_http_version 1.1;
proxy_pass http://practice_web:8000;
}
location /static/ {
alias /static/;
}
}
참고자료
Web Server와 WAS의 차이
서론웹 서버(Web Server)와 웹 애플리케이션 서버(Web Application Server)의 키워드만 두고 보았을 때 두 개의 차이가 뭔가에 대해 확신 있게 대답을 못할뿐더러 아직 이해가 잘 가지 않아서 한번 정리를
dkswnkk.tistory.com
WAS vs 웹 서버
이전 기술면접에서 WAS와 웹서버가 다른 점을 이야기 해보라는 질문에 대답하지 못했었던 경험이 있습니다. 그렇게 기술면접을 망치고...😭 [테코톡] 희봉의 웹서버 vs WAS의 영상을 보게되었습니
velog.io
Web Server와 Web Application Server
Web Server와 Web Application Server
Web Server와 WAS의 차이를 알아보기에 앞서, 먼저 정적 페이지와 동적 페이지에 대해 알아보려고한다.
velog.io
웹 서버 vs WAS
서버 개발에 있어서 가장 기초적인 개념인 웹 서버와 WAS (Web Application Server)의 차이점을 서술할 예정이다.웹 서버의 사전적 정의는 웹 브라우저 클라이언트로부터 HTTP 요청을 받아들이고 HTML 문
velog.io
웹서버와 WAS(Web Application Server)
웹 서버와 WAS(Web Application Server) | 요즘IT
웹 서버는 정적인 데이터를 처리하는 서버입니다. 이미지나 단순 html 같은 정적인 리소스들을 전달하며, WAS만을 이용할 때보다 빠르고 안정적으로 기능을 수행합니다. 반면 WAS는 동적인 데이
yozm.wishket.com
4-09 WSGI
장고 서버를 구동하기 위해 지금까지는 `python manager.py runserver` 처럼 장고의 내장 서버를 구동하는 방식을 사용했다. [[TIP(점프 투 장고)…
wikidocs.net
WSGI 란?
Python 으로 서버 개발을 하다보면 WSGI, uWSGI, Werzeug 등의 단어들이 자주 보인다. 본 포스트에서는 이것들에 대해 알아본다.
sgc109.github.io
Nginx란?
2022.02.21 게시글 등록 2022.10.03 수정 및 추가 - 오타 수정 - Q&A 추가 - 기존글 수정 및 추가 올해 캡스톤 프로젝트에서 NGINX를 사용하게 됐는데 어떤 것인지 잘 몰라서 공부하기로 했다. 🧐 Nginx란?
ssdragon.tistory.com
Nginx란 무엇인가?
서론 토이 프로젝트를 진행하면서 웹 서버로 Nginx를 사용하게 되었는데, 단순히 사용만 하는 것이 아니라 개념부터 확실하게 잡고 가기 위해서 정리를 하게 되었습니다. 웹 서버에 대한 개념은
dkswnkk.tistory.com
Nginx 이해하기 및 기본 환경설정 세팅하기
NGINX Nginx의 개요 엔진엑스(Nginx)는 Igor Sysoev라는 러시아 개발자가 동시접속 처리에 특화된 웹 서버 프로그램이다. Apache보다 동작이 단순하고, 전달자 역할만 하기 때문에 동시접속 처리에 특화되
whatisthenext.tistory.com
Nginx 설치 및 nginx.conf, default.conf 이해하기
Nginx 설치 및 nginx.conf, default.conf 이해하기
1. Nginx란? 가볍고 높은 성능을 가진 웹 서버 (Web Server) 이다. HTTP Server로 활용되며 정적 파일들을 처리하기 위해 사용된다. Reverse Proxy Server로 활용된다. 80번 포트로 들어오는 내용을 3000, 4000, 9000
phsun102.tistory.com
03) Nginx, Gunicorn 배포
[TOC] # 시스템 구성 예시 * 우분투 16.04 * Django * nginx * Gunicorn 다음 설치 예제는 실제 물리서버가 아닌 vultr.com의 가상서버인…
wikidocs.net
Django nginx 연결하기
지난시간에 uWSGI 연결을 완료한 장고 프로젝트를 nginx와 연결하려 한다.nginx는 대표적인 웹 서버 애플리케이션이다.먼저 nginx를 설치한다. (간단하쥬~)nginx를 사용하여 배포하는 사용자는 역시 uWSG
velog.io
[Django] 웹서버, Nginx 사용하기
Django-WSGI-중-uWSGI를-통해-django-실행 [Django] WSGI 중 uWSGI를 통해 django 실행 django-AWS-EC2로-배포 [django] AWS EC2로 배포 Amazon EC2란? EC2란 Amazon Elastic Compute Cloud의 즐임말로서 AWS에서 제공하는 클라우드 컴
ssungkang.tistory.com
Docker + Nginx + gunicorn + django
[실전] Docker + Nginx + gunicorn + django
1) FROM python:3.8파이썬 3.8 버전을 베이스 이미지로 사용2) RUN mkdir /code컨테이너에 /code 디렉토리를 생성3) WORKDIR /code/code 디렉토리로 워킹 디렉토리를 변경4) ADD ./backend/requirements.tx
velog.io
Django: Difference between using server through manage.py and other servers like gunicorn etc. Which is better?
I have been running my beginner Django projects with manage.py runserver. I see suggestions to use gunicorn instead. What is the difference ?
stackoverflow.com
How to use NGINX variables + Reference List
How to use NGINX Variables + Reference List - Status List
Config variables are a powerful tool to control how NGINX routes requests. HTTP request, header and env variables give us precise control on request routing.
statuslist.app
'BE > ETC' 카테고리의 다른 글
API 아키텍처 비교 [REST API vs GraphQL vs gRPC] (7) | 2024.11.25 |
---|