[python] CGI - WSGI - ASGI
참고자료
CGI와 Fast CGI
CGI
- 외부 애플리케이션과 앱 서버와 연결 할 때 사용하는 인터페이스로 보통 CGI(Common Gateway Interface)를 사용
- 웹서버와 일부 프로그램을 연결해주는 표준화된 프로토콜
- CGI는 인터페이스이며 특정 플랫폼에 의존하지 않고, 웹서버로 부터 외부 프로그램을 호출하는 방식을 정의해 놓은 것
- 웹서버가 특정 언어로 쓰인 구체적인 프로그램이 아니라 이 인터페이스에 의존하고 있기 때문에 어떤 어어든 이 인터페이스를 구현하기만 한다면 (CGI 스펙을 따른다면) 웹서버와 소통할 수 있음
- 위의 모형은 가장 일반적인 모습. 과거에는 정적인 HTML 파일 하나를 가지고 웹 서비스를 했기 때문에 이런 CGI 요소가 필요하지 않았음
- 하지만 웹에 대한 수요가 증가함에 따라서 웹 서버가 처리 할 수 없는 정보가 요청되었을 경우 그 처리를 외부 애플리케이션이 할 수 있도록 호출함으로써 중계 역할을 함
Fast CGI
- 그러나 CGI는 클라이언트의 요청이 발생 할 때마다 프로세스를 추가로 생성하고 삭제. 이럴 경우 새로운 프로세스를 생성하고 삭제하는 것이 빈번해지는데 이는 커널 리소스를 계속하여 생성/삭제하기 때문에 오버헤드가 심해지고 성능저하의 원인이됨
- 현대의 웹 서비스처럼 빈번하게 API가 호출되고 요청과 응답을 수시로 반복하여 처리하는 곳에서 이러한 아키텍쳐는 맞지 않음. 그래서 생긴것이 Fast CGI
- Fast CGI는 몇번의 요청이 들어와도 하나의 프로세스만을 가지고 처리. 즉 메모리에 단 하나의 프로그램만을 적재하여 계속 재활용하기 때문에 CGI에 비해여 오버헤드가 월등하게 감소
- Fast CGI는 몇 개의 프로세스가 종료되지 않고 처리를 위해 계속 상주하고 있는 형태이므로 CGI보다는 메모리 소비가 더 큼
- CGI와는 달리 이 프로세스는 웹서버가 아닌 Fast CGI서버가 관리
- 그러나 파이썬에서는 이러한 WAS가 별도로 존재하지 않으며 결국 우리가 CGI, Fast CGI 등을 이용해서 원하는 WAS형태를 만들어 사용해는데 실제로 Python에서는 Python 만의 게이트 웨이 인터페이스가 존재
- mod-python 처럼 웹 서버에 내장 인터프리터로 동작하는 방식도 있음
- 이렇게 하는 경우 내장된 언어를 웹 서버가 해석 할 수 있기 때문에 해당 언어로 서버 프로그래밍 하는 것이 가능
- 하지만 파일을 실행할 때 캐싱을 사용. 따라서 파일의 내용이 바뀌면 웹 서버가 재시작 되어야하는 불편함 존재
- mod_python은 특정 버전의 파이썬 라이브러리에 의존적. 사용하려면 mod_python을 컴파일을 다시 해야하는 불편함이 존재
WSGI
WSGI
- Web Server Gateway Interface
- WSGI는 서버사이드의 서버 API
- WSGI는 파이썬에 종속된 개념. FastCGI는 언어와 상관 없는 socket wire 프로토콜. WSGI가 더 높은 레이어에서 동작. 따라서 둘 다 사용 가능
- Python 애플리케이션, 스크립트가 웹 서버와 통신하기 위한 인터페이스로써 CGI 디자인 패턴을 모태로 하여 만들어진 것이지만 실제 CGI와는 다소 차이가 있음
- WSGI는 CGI와 동일하게 웹 서버와 애플리케이션 중간에 위치하는데, CGI와 다른 점은 CGI는 매 요청마다 프로세스를 생성한다는 점이고, WSGI는 한 프로세스에서 모든 요청을 받는 다는 것
- CGI는 매 요청마다 Fork 등의 함수를 통해 커널 리소스를 추가/반납하고 WSGI는 많은 요청을 콜백으로 받아 처리
- 이러한 WSGI의 대표적인 두 가지 방법
- nginx, apache에서 내장 모듈로 제공하는 server-often high profile 방식 (ex. mod-wsgi, mod-python 등)
- python 코드로 작성된 WAS (gunicorn, uvicorn, cherrypy 등)
- WSGI가 나오기 이전에는 파이썬의 웹 애플리케이션 프레임워크에서 웹서버를 선택 할 때 제약이 있었음
- 보통 CGI, FastCGI, mod_python 중에 하나를 선택해야했음
- 근데 로우레벨로 만들어진 WSGI가 등장함으로써 웹서버와 웹 어플리케이션, 프레임워크 간에 벽이 허물어짐
- WSGI는 서버와 게이트웨이, 애플리케이션과 프레임워크 양 단으로 나뉘어져 있음
- WSGI에서 리퀘스트를 처리하면 서버 단에서 환경 정보와 콜백함수를 애플리케이션 단에 제공. 애플리케이션은 그 요청을 처리하고 미리 제공된 콜백함수를 통해 서버단에 응답
- 이때 WSGI 미들웨어가 WSGI서버와 애플리케이션 사이를 중계. 이 미들웨어는 서버 관점에서 애플리케이션으로 애플리케이션 관점에서는 서버로서 행동
- 정리: 요청 → 웹서버 (apache/nginx) → WSGI미들웨어 → WSGIa를 지원하는 웹 어플리케이션 프레임워크
- WSGI의 단점은 요청을 받고 응답을 반환하는 단일 동기 호출방식으로 처리 된다는 점. 오랜 시간 연결을 유지하는 WebSocket이나 긴 HTTP 요청을 처리하기에 적합하지 않음
ASGI
ASGI
- Asynchronous Server Gateway Interface
- WSGI만으로도 우리는 충분히 클라이언트의 요청을 웹 서버가 받아 내 애플리케이션으로 올 수 있도록 구성할 수 있음. 하지만 이것만으로는 현대의 웹 서비스의 대용량 트래픽 처리를 유연하게 하기 위한 만족된 조건을 충족하기 어려운 점이 있음
- ASGI는 WSGI의 상위호환으로 web server와 프레임워크 애플리케이션을 연결해주는 python의 표준 api
- python에서는 asyncio. coroutine과 같은 비동치 처리를 지원. 그러나 WSGI는 동기 함수 처리만을 지원하여 여러 작업을 동시에 처리하는 것에 한계가 있음
- 웹 소켓등을 사용한 실시간 채팅 서비스 등을 할 수도 있는데 WSGI로는 이러한 서비스를 구현하는데 어려움이 있음
- 물론 할 수는 있지만 대용량 트레이싱 등과 같은 유지보수, 기본적인 구현이 쉽지 않음
- 최근에는 django3.0 뿐만 아니라 FastAPI 등의 프레임 워크에서도 ASGI 인터페이스를 적용했으며 뒤따라 Falcon 프레임워크도 3.0부터는 ASGI 개발에 들어감
WSGI, ASGI를 사용하는 이유
- django 웹 어플리케이션 서버 아키텍쳐는 빨간색 박스와 같이 django 프레임워크 내부의 url과 web server가 통신하게 됨
- 이 사이에 django프레임워크 안에 미들웨어로서 ASGI / WSGI가 존재
- 왜 사용 ??!?! → 이유는 간단 !
- 흔히 웹 서버로 사용되어져있는 Apache HTTP Server와 Tomcat은 Java기반이므로 Python 코드를 읽을 수 없음
- 만약 WSGI / ASGI 미들웨어를 사용하지 않으면 사용할 수 있는 웹서버가 굉장히 한정적
- 따라서 최적의 솔루션은 Apache 재단의 웹서버 뿐만 아니라 모든 웹 서버와 python 계열의 프레임워크가 통신 할 수 있게 해주는 미들웨어가 필요
- 성능면에서도 검증이 되어 있고, 모두가 익숙한 아파치 웹서버를 이용하는 것이 좋음