web/snulion

WAS, WSGI, ASGI에 대해 araboza

민사민서 2024. 11. 2. 16:12

django는 웹 개발 프레임워크일 뿐이지, 웹 서버는 아님

물론 django에서는 python manage.py runserver 커맨드를 통해 장고에서 기본적으로 제공하는 개발용 내장 서버 사용할 수 있다

=> ssl 등 보안 프로토콜 적용 불가, 여러 프로세스 동시에 처리 불가

 

then, What's web server?

웹 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고, HTML 문서와 같은 웹 페이지를 반환하는 컴퓨터 프로그램

클라이언트 요청(주로 HTTP)에 맞는 응답(주로 web page 혹은 api 응답)을 생성

 

상기 언급한 웹 서버에서는 지정된 경로에 미리 데이터를 준비한 후 요청에 따라 그대로 돌려주는 역할의 정적 콘텐츠 서빙만을 수행 가능함

ex) public 폴더에 들어갈만한 이미지/소개문구들 ...

 

CGI(Common Gateway Interface)

언어에 무관하게 웹 서버에서 요청을 처리할 수 있도록 지원하는 인터페이스

=> 하지만 아래와 같은 단점이 있음

  • 매 HTTP 요청마다 새로운 프로세스를 생성해야 함
  • 매 HTTP 요청마다 데이터베이스 연결을 새롭게 생성해야 함
  • 높은 트래픽에서 메모리 문제로 성능 저하가 일어날 수 있음

WSGI and ASGI

기술이 발전하면서 보다 동적인, 복잡한 로직을 필요로 하는 요청들이 비중 증가

=> 웹 서버에서 감당하기 어려운 부하, 별도의 서버를 두는 식으로 해결

 

cf) 장고에서 python manage.py runserver 실행 시

 

WSGI, Web Server Gateway Interface

- CGI의 경우 서버 디렉토리 내 단순 스크립트를 실행하는 형태였다면 WSGI는 Python 한정 보다 복잡하고 상세한 비즈니스 로직을 프레임워크 등을 통해 수행할 수 있다

- WAS(web application server)를 구현하기 위한 인터페이스

 

=> 이런 WSGI의 구현체에는 gunicorn, uvicorn 등이 있어요

 

정리하자면

1) 정적인 콘텐츠를 처리하는 웹 서버를 앞단에 두고

2) 동적인 요청은 별도의 어플리케이션 서버(WAS)로 위임하며

3) Python의 경우 CGI와 유사한 WSGI(+ASGI)를 구현하는 프레임워크에서 해당 로직을 처리하도록 구성되어 있는 형태

 

  • 동적 콘텐츠를 지원하기 위해 비즈니스 로직이 담긴 별도의 애플리케이션 작성(=Django)
  • 웹 애플리케이션 서버(WAS) 형태로 해당 애플리케이션을 실행
  • 실제 HTTP 요청을 받는 웹 서버와의 통신을 위해 WSGI 사용
  • 따라서 WAS는 WSGI를 구현하는(지원하는) 형태여야 함

 

WSGI & ASGI

실시간 채팅 서버를 구현하기 위해 WebSocket 프로토콜을 사용하는 WAS 서버를 계획하고 있다면

=> WSGI가 아니라 ASGI를 사용해야 함

=> why? 비동기 요청은 실시간성 및 다중 연결성이 중요한 WebSocket 연결에서 필수적인 요소

Django 애플리케이션을 WAS로 실행시키기 위해서도 ASGI를 구현하는 Uvicorn 등을 사용해야 함

 

=> 즉, ASGI 구현체를 통해 웹 서버를 띄워 Django를 실행해야 한다.

 

지금까지의 사고흐름:

 

Web Application Server(WAS)

위 상황에서의 WAS = Python 기반 웹 프레임워크에서 HTTP 요청을 처리할 수 있도록 하며 애플리케이션 로직을 호출하고 송수신하는 서버

 

Q. 웹 서버는 무슨 일을 하나요?

  • 클라이언트(브라우저 or 프론트엔드 서버)로부터 요청을 받아 응답을 되돌려 줍니다.
  • 전통적인 의미의 웹 서버는 미리 준비된 정적인 콘텐츠만 반환할 수 있습니다.
  • WSGI 서버 등을 포함한 넓은 의미의 웹 서버는 정적인 콘텐츠는 물론 애플리케이션과의 통신을 통해 동적인 콘텐츠도 생성할 수 있습니다.

Q. 서버는 어떻게 Django와 요청을 주고받나요?

  • 웹 애플리케이션 서버(e.g. Gunicorn)는 실행될 때 Django 애플리케이션을 포함한 WSGI 애플리케이션 인스턴스를 생성하고 이를 메모리에 유지합니다.
  • wsgi.py 에 정의된 WSGI 애플리케이션 인스턴스(e.g. Django)를 미리 만들어 요청이 들어올 때마다 활용합니다.
  • 사전에 지정한 프로세스의 수(=workers)만큼의 인스턴스를 띄워 병렬 처리를 지원합니다.
  • 즉, 하나의 WAS 내에서 웹 서버(HTTP 요청 처리)와 WSGI 서버(애플리케이션 처리) 역할이 동시에 수행됩니다.

Q. 그럼 Gunicorn, Uvicorn만으로 HTTP 요청을 처리하는 서버를 만들 수 있는건가요?

  • 네, 전통적인 의미의 웹 서버 기능을 모두 포함합니다.
  • 그러나 대부분의 배포 환경에서는 Nginx와 같은 웹 서버를 앞단에 배치합니다.
  • 이는 정적 콘텐츠 제공, 로드 밸런싱 및 보안 기능 등을 효율적으로 사용하기 위함입니다.

 

possible django server architecture w/ websocket

  • 기존의 Django 인스턴스를 WSGI가 아닌 ASGI로 설정함으로써 WebSocket과 같은 비동기 요청 처리
  • 단일 ASGI 서버 인스턴스 내에서 프로토콜을 식별 후 HTTP 요청 → 기존 라우팅 / WebSocket 요청 → WebSocket 전용 소비자(Consumer)로 연결
  • WebSocket 요청이 비동기적으로 동작할 동안 HTTP 요청은 동기적으로 처리

그럼 다음 게시물에서 React + Django 구현 관련 고려할 점을 간단하게 알아봅시다