내가 보려고 만든 django 분석 - 3 (asgi, wsgi)

sihwan_e·2021년 5월 30일
5

요약

일반적으로 웹 서버는 python으로 되어 있지 않다. 그래서 python으로 되어있는 웹 프레임워크인 django와 소통해줄 중간 개체가 필요하다.

역사

1. CGI (Common Gateway Interface)
외부 애플리케이션과 웹서버(nginx, Apache)와 연결할 때 사용하는 인터페이스.
과거, 정적 HTML 하나로 웹 서비스를 하였던 때(웹 서버가 정적 파일등을 사용자에게 다운로드 방식으로 제공)와 달리, 웹에 대한 수요가 증가함에 따라 웹 서버로 처리할 수없을때, 그처리를 외부 애플리케이션이 할 수있게 중계역할을 해준다. 하지만 CGI는 클라이언트의 요청이 발생할 때 마다 프로세스를 추가,생성,삭제를 해야한다.
그래서 많은 사용자가 동시 요청을 하게 되면 성능 저하가 발생한다.

2. FastCGI
현대의 웹 서비스는 REST API가 빈번히 발생하며, 요청과 응답을 수없이 반복처리해야한다. 그래서 FastCGI가 등장한다. 하나의 프로세스로 여러 요청을 처리할 수 있다. java에는 Tomcat이 웹서버와 +fastCGI를 포함한 형태이고 다수 사용자 접속에 유리하며, 현재 한국 많은 기업들이 자바를 언어로 쓰고있다.

3. WSGI
파이썬에는 파이썬 만의 게이트웨이 인터페이스가 존재한다. 그것이 WSGI
스크립트가 웹 서버와 통신하기 위한 인터페이스이며, CGI 디자인 패턴을 참고한 것이지만 실제 CGI와는 차이가 있다.
웹 서버가 애플리케이션의 코드를 직접적으로 읽을수 없기때문에, 중간에서 미들웨어가 해당 코드를 읽어 결과를 대신 반환해주는 것이다.
WSGI의 대표적인 방법
( nginx, apache 에서 내장 모듈로 제공하는 server-often high profile 방식) ,
( Python 코드로 작성된 Web App Server ( gunicorn, uvicorn 등)

본문

django -admin startproject 를 통해 생기는 메인 프로젝트의 디렉토리에는 asgi.py 와 wsgi.py가 생성된다.

django는 웹 프레임 워크일 뿐이므로 작동하기 위해 웹 서버가 필요하다. 하지만 대부분의 웹 서버는 기본적으로 Python을 사용하지 않는다. 그래서 그 사이에서 커뮤니케이션을 이루어줄 인터페이스가 필요하다.

그 인터페이스가 되어주는 것이 WSGI 와 ASGI 인 것이다.

WSGI : (Web Server Gateway Interface)

웹 서버와 애플리케이션 사이의 통신을 위한 주요 파이썬 표준 (동기(Synchronous)식 코드만 지원)
WSGI는 HTTP스타일로 request/response 형식에 고정되어 있다. 즉 , 단일 처리만 가능한 동기 호출 방식이다.
그래서 긴 대기시간을 가지는 HTTP 연결에는 적합하지 않다.

HTTP는 Connection이 짧게 유지되는 특성을 지니고 있었기 때문에, Long-Polling HTTP와 WebSocket 같이 상대적으로 connection이 긴 특성을 지닌 Protocol과는 맞지 않았다.
HTTP Request는 application내부에서 오직 하나의 path를 가질 수 있기 때문에, 여러개의 path를 통해 이벤트를 수신하는 WebSocket의 이벤트를 처리할 수 없었다.

ASGI : (Asynchronous Server Gateway Interface)

DJANGO사이트에서 비동기 Python 기능과 비동기 Django 기능을 개발하면서 사용할 수 있게 해주는 새로운 비동기 친화적 표준. request/response로 이루어진 WSGI와 달리 send/ receive 로 되어 있어 비동기적으로 이벤트 처리가 가능하다. 그로인해 여러 송수신 이벤트가 가능하다. WSGI의 상위 집합으로 설계되어있으며 asgiref 라이브러리를 통해 ASGI 서버 내에서 WSGI를 실행 할 수도 있다고 한다.
(python의 비동기 처리 라이브러리 asyncio와 async/await를 공부해야한다.)
django 3.0 에서부터 Channels 기능을 제공하고 있으며, 이것은 ASGI 기반으로 만들어 진것이다.
기존의 HTTP 통신을 넘어, 웹 소켓, 채팅 프로토콜, ioT 프로토콜 등을 처리할 수 있다. (django로 채팅 만들어볼 것)

gunicorn, nginx

wsgi 는 파이썬에서 어플리케이션이 웹서버와 통신하기위한 인터페이스

wsgi server(middleware)은 웹서버와 WSGI를 지원하는 웹어플리케이션 사이에서 동작하고 gunicorn, uwsgi등이 있다.

gunicorn만 있어도 http request를 처리할순있지만,gunicorn에는 없고 nginx에는 있는 기능떄문에 둘을 연동해서 쓴다.

(1. djangodml media, css등 static한 요청은 직접처리하고 다이나믹한 요청을 gunicorn에 넘긴다. 지유니콘으로 넘어가는순간 자원사용이 크게늘어 스태틱한 요청을 따로 처리해주는게 중요하다.

  1. nginx는 c로 구현되어 속도와 메모리 사용측면에서 뛰어나다.

둘을 연동하면 동시에 많은 요청을 처리할수있고, 훨씬 안정화된 서버를 구축할수 있게된다.

장고 의 runserver 는 단일 프로세스 , 단일쓰레드라 nginx에서 아무리 많은 요청을 처리해도 결국 django 내장서버에서 병목이 생긴다)

Synchronous vs Asynchronous

동기식 코드란 위에서 아래로 부터 내려오며 코드 실행이 진행되는 방식을 말함
그와 반대로 비동기(Asynchronous))적 코드는 쉽게 말해 동기식 코드가 실행되고 난 뒤 실행되는 코드이다.
둘은 런타임시 발생하는 지연시간에 가장 큰 차이가 있다. 동기식 코드는 앞의 작업이 아직 끝나지 않으면 뒤는 가만히 기다리고 있어야한다. 순서대로 진행되기 때문에 유지와 보수가 쉽고, 코드의 파악이 쉽다. 그래서 평소 python으로 코드를 짤때 print() 등으로 breakpoint를 둬서 한 단계씩 디버깅을 하며 에러를 잡아낸다.

반면 비동기식 코드는 단계별로 독립적인 작업이라면 순차적으로 진행되지 않아도 되며, 동시에 종료될 필요도 없다.
하나의 쓰레드로 동시 처리를 하는 것이다.
쉽게 말해 직렬과 병렬느낌이랄까. 향후 자바스크립트를 공부할때 다시 제대로 더 살펴보도록 해야겠다.

profile
Sometimes you gotta run before you can walk.

0개의 댓글