WSGI, CGI, ASGI란?

이정규·2021년 10월 19일
2

전에 프로젝트를 할 때에는 Nginx - Flask를 직접 연결하여 사용했었다.
하지만, 이번 프로젝트를 진행하면서 코치님이 Gunicorn이라는 WSGI미들웨어 서버를 Nginx와 Flask사이에 넣어서 배포해보라고 하셨다.
일단 Guicorn을 사용해서 배포하긴 했는데 Gunicorn이 뭔지 몰랐다. Guicorn에 대해 알아보니 WSGI란다. 대체 WSGI가 뭘까?

WSGI를 알기 위해서는 일단 CGI를 알아볼 필요가 있다. WSGI는 CGI를 기반으로 만들어졌기 때문이다.

CGI(Common Gateway Interface)

웹 서버에서 어플리케이션을 작동시키기 위한 인터페이스이다.
정적으로 동작하는 웹서버를 동적으로 기능하게 만들기 위함이다.
웹서버에 들어온 Request를 외부 프로그램과 연결하여 해당 프로그램이 그 요청을 처리하게 연결해주는 역할이다.
들어온 요청을 연결해주는 역할만 할 뿐, 웹 서버가 외부 프로그램을 직접 실행한다.
요청 -> 웹서버(nginx, apache) -> (웹서버가 직접 실행)프로그램

정적으로 들어오는 요청은 웹서버에서 바로 처리가 가능하지만 이제 동적으로 처리해야 할 일이 많아지게 된다면, 문제가 생긴다. 바로 밑에 단점에 나와있다.

  • 단점
    요청이 들어올 때 마다 fork를 통해 프로그램을 계속해서 실행한다.
    이는 요청이 올 때 마다 DB Connection을 새로 열어야 한다는 말이 된다.
    그렇기 때문에 서버 메모리가 많이 잡아먹게 된다.

WAS(Web Application Server)

WAS는 결국 Web Server + CGI의 형식이지만 CGI가 웹서버에 있는게 아닌 떨어져 나왔다고 생각하면 된다.
이제 웹서버에서 직접 실행하는 것이 아닌, 웹어플리케이션이 앱을 실행하는 것이다.
그렇게 함으로써 웹서버는 웹어플리케이션 서버에게 요청을 하고, 웹 어플리케이션은 실행된 앱에게 요청을 전달하게 된다.
요청 -> 웹서버(nginx, apache) -> 웹앱 서버(tomcat, JBoss등) -> (웹앱 서버가 직접 실행)프로그램

  • CGI와 WAS의 차이점
    CGI는 요청이 올 때마다 프로세스를 실행시켜 동적 컨텐츠를 만든다.
    WAS는 쓰레드를 실행시켜 동적 컨텐츠를 만든다.
    그래서 WAS는 CGI보다 메모리를 덜 잡아먹게 되고, 속도도 더 빠르다.

궁금점

Spring을 할 때도 똑같이 실행시키면 톰캣으로 실행되고 localhost:8080으로 접속하면 가능하다.
그리고 flask도 실행시키면 localhost:5000번으로 접속하면 가능하다.

Spring을 Nginx와 연동할 땐 localhost:8080으로 redirect하면 된다.
flask도 마찬가지로 localhost:5000으로 redirect하면 된다. 첫 프로젝트때에는 이런식으로 진행했었다.

그런데 왜? flask만 WSGI를 써야할까??
DJANGO는 웹서버 인가 ? 🤔
구글링을 하며 열심히 찾아보던 중 이러한 글이 있었다. 그래서 Django도 이런 말이 있으니 Flask 공식문서에 가도 이런말이 있을까?
Flask 공식문서 배포옵션
있다.. 개발중에만 내장 서버를 이용하고, 운영중에는 내장 개발 서버를 사용하지마라! 라고 적혀있었다.
그래서 WSGI를 사용해야 하는 것이다. 이거 찾느라 고생했는데 역시 공식문서를 찾아보는 습관을 들여야한다.

WSGI(Web Server Gateway Interface)

왜 써야하는지 알았으니 어떻게 구성이 되어있는지 알아보자.
요청 -> 웹서버(nginx, apache) -> WSGI 서버(gunicorn, uWSGI등) -> WSGI를 지원하는 웹 어플리케이션(Flask, Django등)

이런식으로 WSGI는 웹서버와 flask사이에 껴있는 상태이다.

Bjoern, uWSGI, mode_wsgi, CherryPy, Gunicorn이 있다. 각 특징은 다음과 같다.

Bjoern: 압도적인 처리량을 자랑함, 적은 메모리 사용량,적은 에러
CherryPy: 괜찮은 처리량, 매우 빠른 latency, 0에러
Gunicorn: 적은 에러,
Meinheld: 적은 메모리 사용량, 넘치는 에러
mod_wsgi: 모르겠다..

uWSGI: 느린 처리량, 끔찍한 latency, 메모리를 메우 잡아먹음,

ASGI(Asynchronous Server Gateway Interface)

위 WSGI만으로도 대용량 트래픽 처리를 유연하게 하기 위한 만족된 조건을 충족하기 어려운 점이 있었다.

바로 WSGI는 동기적으로만 작동하기에 여러 작업을 동시에 처리하는데 한계가 존재하는 것이다. 물론 비동기 큐, Celery를 잘만 활용한다면 가능하지만 구현이 쉽지가 않다.

그래서 요청을 비동기로 처리할 수 있는 ASGI가 등장했다.

대표적으로는 Uvicorn이라는 것이 있다. 하지만 아직 ASGI는 직접 써보지 않아 감이 오질 않는다.

성능 비교

위 방식들을 사용하며 성능 측정한 포스트가 있어 달아둔다.
https://jihooyim1.gitbooks.io/linuxbasic/content/contents/12.html

참고
https://brownbears.tistory.com/350
https://paphopu.tistory.com/entry/WSGI%EC%97%90-%EB%8C%80%ED%95%9C-%EC%84%A4%EB%AA%85-WSGI%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
https://hello-world.kr/40
https://helloworld-88.tistory.com/71
https://blog.neonkid.xyz/249
https://perpetual.tistory.com/155

profile
강한 백엔드 개발자가 되기 위한 여정

0개의 댓글